Compare commits
61 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cf41d12d22 | |||
| 18714e6142 | |||
| 4936099c39 | |||
| f1471763f5 | |||
| 5850793b67 | |||
| fc1745c652 | |||
| 43d0449904 | |||
| b842e82f77 | |||
| 98ccbd4704 | |||
| dba755dcec | |||
| 8f3a478771 | |||
| 9ea41eed78 | |||
| ff421d39f6 | |||
| 635f6febe4 | |||
| 62af5649fe | |||
| 710761e2d5 | |||
| 74520b8333 | |||
| 7f3d6ed8cd | |||
| eed6487114 | |||
| 2c2aaa0653 | |||
| e610a412b9 | |||
| 8ba35a0d56 | |||
| b75d5c8c30 | |||
| 9bbb4f2af8 | |||
| ec219c5830 | |||
| 731efaedaf | |||
| 3723e3b7e7 | |||
| 62c562a3f1 | |||
| 456267a771 | |||
| edb0670670 | |||
| 872120c757 | |||
| f3660e92a1 | |||
| b0f4d6c493 | |||
| 627eb534a2 | |||
| 2b612ed5d4 | |||
| 8392f44c45 | |||
| 58a9eda311 | |||
| fb0bb553f3 | |||
| 9e59c51f3c | |||
| 3d74472a4c | |||
| acbe858995 | |||
| 3ae07cc7b0 | |||
| 33d2574b72 | |||
| 0c2d1c41ae | |||
| 31d12e4194 | |||
| b784750f69 | |||
| 9387c57c3b | |||
| 96c57c43ba | |||
| 192b277229 | |||
| e2e8f0a1e6 | |||
| f0454650a2 | |||
| 4b24368be2 | |||
| c199a13a7f | |||
| 290a637883 | |||
| 40d800195a | |||
| f3034d23f7 | |||
| d337fcb265 | |||
| 4171aadfff | |||
| 9a6014d65b | |||
| 8cdd1512d1 | |||
| 64c1789fcc |
+37
-39
@@ -34,12 +34,12 @@ jobs:
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
apt-get update -qq
|
||||
apt-get install -y gcc libcurl4-openssl-dev apt-transport-https ca-certificates
|
||||
apt-get install -y gcc curl libcurl4-openssl-dev apt-transport-https ca-certificates
|
||||
echo "deb [trusted=yes] https://packages.cloud.google.com/apt cloud-sdk main" \
|
||||
> /etc/apt/sources.list.d/google-cloud-sdk.list
|
||||
apt-get update -qq && apt-get install -y google-cloud-cli
|
||||
|
||||
- name: Download El runtime from Artifact Registry
|
||||
- name: Authenticate to GCP + stage PINNED El runtime
|
||||
env:
|
||||
GCP_SA_KEY: ${{ secrets.GCP_SA_KEY }}
|
||||
run: |
|
||||
@@ -47,41 +47,21 @@ jobs:
|
||||
gcloud auth activate-service-account --key-file=/tmp/gcp-key.json
|
||||
gcloud config set project neuron-785695
|
||||
|
||||
# PINNED RUNTIME — do NOT pull "latest" from Artifact Registry.
|
||||
# The ship-soul calls engram_prune_telemetry (awareness.el sync/heartbeat
|
||||
# self-review). The latest published el-runtime-c no longer defines that
|
||||
# symbol, so an unpinned build fails to LINK — which is exactly how a
|
||||
# broken/handlerless soul reached prod before. Compile against the
|
||||
# vendored release runtime v1.0.0-20260501: the exact runtime the merged
|
||||
# ship-soul was verified against (verify-soul-contract GATE PASS +
|
||||
# genesis boot survives + full safety-contact response). It is committed
|
||||
# under vendor/ so the soul build is fully reproducible and never depends
|
||||
# on a moving AR "latest".
|
||||
rm -rf /opt/el/runtime
|
||||
mkdir -p /opt/el/runtime
|
||||
|
||||
# Get latest version of each runtime package (elc/elb not needed — we compile
|
||||
# dist/soul.c directly; running elb on Linux OOM-kills the runner, and we
|
||||
# always use the repo's pre-built soul.c anyway).
|
||||
get_latest() {
|
||||
gcloud artifacts versions list \
|
||||
--repository=foundation-prod \
|
||||
--location=us-central1 \
|
||||
--project=neuron-785695 \
|
||||
--package="$1" \
|
||||
--sort-by="~createTime" \
|
||||
--limit=1 \
|
||||
--format="value(name)" 2>/dev/null | awk -F/ '{print $NF}'
|
||||
}
|
||||
|
||||
RC_VER=$(get_latest el-runtime-c)
|
||||
RH_VER=$(get_latest el-runtime-h)
|
||||
|
||||
echo "Downloading runtime@${RC_VER}"
|
||||
|
||||
gcloud artifacts generic download \
|
||||
--repository=foundation-prod --location=us-central1 --project=neuron-785695 \
|
||||
--package=el-runtime-c --version="${RC_VER}" \
|
||||
--destination=/opt/el/runtime/
|
||||
|
||||
gcloud artifacts generic download \
|
||||
--repository=foundation-prod --location=us-central1 --project=neuron-785695 \
|
||||
--package=el-runtime-h --version="${RH_VER}" \
|
||||
--destination=/opt/el/runtime/
|
||||
|
||||
mv /opt/el/runtime/el_runtime.c* /opt/el/runtime/el_runtime.c 2>/dev/null || true
|
||||
mv /opt/el/runtime/el_runtime.h* /opt/el/runtime/el_runtime.h 2>/dev/null || true
|
||||
echo "El runtime ready: $(ls /opt/el/runtime/)"
|
||||
cp vendor/el-runtime/v1.0.0-20260501/el_runtime.c /opt/el/runtime/el_runtime.c
|
||||
cp vendor/el-runtime/v1.0.0-20260501/el_runtime.h /opt/el/runtime/el_runtime.h
|
||||
echo "El runtime PINNED to v1.0.0-20260501: $(ls /opt/el/runtime/)"
|
||||
|
||||
- name: Build neuron soul binary
|
||||
run: |
|
||||
@@ -94,19 +74,37 @@ jobs:
|
||||
# entirely: elb on Linux would OOM the runner (elc uses 24GB+ virtual memory
|
||||
# on a 16GB host) and we always restore from the repo's soul.c anyway.
|
||||
mkdir -p dist
|
||||
cc -O2 -DHAVE_CURL \
|
||||
# -rdynamic: the el runtime resolves the HTTP request handler (and the
|
||||
# tool handlers) by NAME via dlsym(RTLD_DEFAULT, "handle_request").
|
||||
# macOS exports these symbols freely, but glibc/Linux only makes symbols
|
||||
# visible to dlsym if they are in the dynamic symbol table — so without
|
||||
# -rdynamic the stripped Linux binary boots but returns "el-runtime: no
|
||||
# http handler registered" for EVERY route (i.e. a soul that serves
|
||||
# nothing). Same reason the Windows build links -Wl,--export-all-symbols.
|
||||
cc -O2 -DHAVE_CURL -rdynamic \
|
||||
-I$RUNTIME \
|
||||
dist/soul.c \
|
||||
$RUNTIME/el_runtime.c \
|
||||
-lssl -lcrypto -lcurl -lpthread -lm \
|
||||
-o dist/neuron
|
||||
|
||||
# Strip debug symbols and non-essential symbol table entries.
|
||||
# -s removes the symbol table + relocation info (max size reduction).
|
||||
# Keeps the binary functional; debuggability is preserved via source + CI logs.
|
||||
# -s strips .symtab + debug for size. .dynsym (which -rdynamic populated
|
||||
# with the dlsym-resolved handlers) is preserved, so the handler still
|
||||
# resolves after stripping.
|
||||
strip -s dist/neuron
|
||||
ls -lh dist/neuron
|
||||
|
||||
- name: Soul contract gate (HARD BLOCK — no destructive/stale soul publishes)
|
||||
run: |
|
||||
# Boots dist/neuron on a throwaway port with a throwaway HOME/engram/cgi
|
||||
# (never touches ~/.neuron or any live service) and fails the build if any
|
||||
# app-contract route is unanswered (PRESENCE) or any engram write route
|
||||
# hard-deletes instead of tombstoning/superseding (IMMUTABILITY). Non-zero
|
||||
# here blocks Publish -> Artifact Registry -> GKE deploy, so a stale or
|
||||
# memory-destroying soul can never reach prod.
|
||||
chmod +x dist/neuron scripts/verify-soul-contract.sh
|
||||
bash scripts/verify-soul-contract.sh dist/neuron 7796
|
||||
|
||||
- name: Smoke test
|
||||
run: |
|
||||
file dist/neuron
|
||||
|
||||
+259
-17
@@ -125,6 +125,13 @@ fn emit_heartbeat() -> Void {
|
||||
let boot: String = if str_eq(boot_raw, "") { "0" } else { boot_raw }
|
||||
let idle: String = int_to_str(idle_count())
|
||||
let ts: Int = time_now()
|
||||
// idle_ms (2026-07-30 self-review): wall-clock ms since the last inbound
|
||||
// HTTP request (stamped in routes.el handle_request). This is the real
|
||||
// "time since anyone talked to me" signal; the legacy tick-based idle
|
||||
// field above only counts ticks since the last inbox synthesis-request
|
||||
// and in practice always equals pulse. -1 = no request seen this boot.
|
||||
let last_act_raw: String = state_get("soul.last_activity_ts")
|
||||
let idle_ms: Int = if str_eq(last_act_raw, "") { 0 - 1 } else { ts - str_to_int(last_act_raw) }
|
||||
let nc: Int = engram_node_count()
|
||||
let ec: Int = engram_edge_count()
|
||||
let wmc: Int = engram_wm_count()
|
||||
@@ -180,7 +187,128 @@ fn emit_heartbeat() -> Void {
|
||||
// (2026-07-19 self-review)
|
||||
let sync_ok_raw: String = state_get("soul.last_sync_ok_ts")
|
||||
let sync_age: Int = if str_eq(sync_ok_raw, "") { 0 - 1 } else { ts - str_to_int(sync_ok_raw) }
|
||||
let payload: String = "{\"event\":\"heartbeat\",\"pulse\":" + pulse + ",\"tick\":" + pulse + ",\"boot\":" + boot + ",\"idle\":" + idle + ",\"node_count\":" + int_to_str(nc) + ",\"edge_count\":" + int_to_str(ec) + ",\"node_delta\":" + int_to_str(node_delta) + ",\"edge_delta\":" + int_to_str(edge_delta) + ",\"wm_active\":" + int_to_str(wmc) + ",\"wm_delta\":" + int_to_str(wm_delta) + ",\"sync_added_total\":" + sat_str + ",\"sync_age_ms\":" + int_to_str(sync_age) + ",\"wm_avg_weight\":" + wm_avg_str + ",\"wm_top\":" + wm_top + ",\"ts\":" + int_to_str(ts) + ",\"uptime_ms\":" + int_to_str(up_ms) + ",\"uptime\":\"" + up_human + "\",\"embed_ok\":" + int_to_str(emb_ok) + ",\"ise_fail\":" + fail_str + "}"
|
||||
// Embedding pump + real coverage (2026-07-25 self-review): the
|
||||
// authoritative :8742 store's lazy backfill only runs inside
|
||||
// engram_activate, and nothing calls /api/activate there in production —
|
||||
// embedded_count stalled at 93/12175 after a restart from a snapshot
|
||||
// without vectors. Pump up to 32 embeds per heartbeat via the new
|
||||
// /api/embed-backfill route (route persists the snapshot when it embeds
|
||||
// anything, so vectors survive the next restart; self-limiting once
|
||||
// coverage is full) and surface the store's true coverage here.
|
||||
// embed_ok alone is misleading — it pings the Ollama root, not the
|
||||
// embed pipeline. embed_count=-1 means the route was unreachable.
|
||||
// URL resolution mirrors ise_post: env -> state -> localhost constant.
|
||||
let hb_env_url: String = env("SOUL_ISE_URL")
|
||||
let hb_state_url: String = if str_eq(hb_env_url, "") { state_get("soul_engram_url") } else { hb_env_url }
|
||||
let hb_engram_url: String = if str_eq(hb_state_url, "") { "http://localhost:8742" } else { hb_state_url }
|
||||
let bf_resp: String = http_get(hb_engram_url + "/api/embed-backfill?n=32")
|
||||
let bf_done_raw: String = json_get(bf_resp, "embedded")
|
||||
let bf_done: String = if str_eq(bf_done_raw, "") { "-1" } else { bf_done_raw }
|
||||
let bf_total_raw: String = json_get(bf_resp, "embedded_count")
|
||||
let bf_total: String = if str_eq(bf_total_raw, "") { "-1" } else { bf_total_raw }
|
||||
// WM regime observability (2026-07-25 self-review): the "same 2 nodes
|
||||
// pinned at a saturated cap" failure took cross-referencing the ISE
|
||||
// stream by hand to spot. Make it one-glance: wm_saturated flags the
|
||||
// cap-pinned regime; wm_top0_streak counts consecutive heartbeats with
|
||||
// the same node in WM slot 0 (state-tracked, same mechanism as wm_delta).
|
||||
let wm_sat: Int = if wmc >= 24 { 1 } else { 0 }
|
||||
// Saturation TRANSITION event (2026-08-01 self-review): wm_saturated is a
|
||||
// sampled boolean — the 0→1 onset and 1→0 release moments were only
|
||||
// recoverable by diffing consecutive heartbeats by hand. Emit a discrete
|
||||
// low-rate ISE at each edge, carrying the WM top-5 at that instant so the
|
||||
// composition that CAUSED the regime change is captured, not the
|
||||
// composition 59 seconds later. State-tracked like wm_delta; first beat
|
||||
// of a boot never fires (prev defaults to current) — a restart is not a
|
||||
// transition.
|
||||
let prev_sat_raw: String = state_get("soul.prev_wm_saturated")
|
||||
let prev_sat: Int = if str_eq(prev_sat_raw, "") { wm_sat } else { str_to_int(prev_sat_raw) }
|
||||
if wm_sat != prev_sat {
|
||||
let sat_dir: String = if wm_sat == 1 { "onset" } else { "release" }
|
||||
ise_post("{\"event\":\"wm_saturation_transition\",\"direction\":\"" + sat_dir + "\",\"wm_active\":" + int_to_str(wmc) + ",\"wm_top\":" + wm_top + ",\"ts\":" + int_to_str(ts) + "}")
|
||||
}
|
||||
state_set("soul.prev_wm_saturated", int_to_str(wm_sat))
|
||||
let wm_top0: String = json_array_get(wm_top, 0)
|
||||
let wm_top0_id: String = json_get(wm_top0, "id")
|
||||
let prev_top0: String = state_get("soul.prev_wm_top0")
|
||||
let t0streak_raw: String = state_get("soul.wm_top0_streak")
|
||||
let t0streak_prev: Int = if str_eq(t0streak_raw, "") { 0 } else { str_to_int(t0streak_raw) }
|
||||
// 2026-07-26 self-review: guard the empty-id case — before the runtime
|
||||
// emitted "id" in wm_top JSON, ""=="" incremented the streak every beat
|
||||
// (streak measured uptime, not fixation). Empty id now resets to 0.
|
||||
let t0streak: Int = if str_eq(wm_top0_id, "") { 0 } else { if str_eq(wm_top0_id, prev_top0) { t0streak_prev + 1 } else { 1 } }
|
||||
state_set("soul.prev_wm_top0", wm_top0_id)
|
||||
state_set("soul.wm_top0_streak", int_to_str(t0streak))
|
||||
// wm_churn (2026-07-26 self-review): count of current top-5 WM ids absent
|
||||
// from the previous heartbeat's top-5. Distinguishes "one stuck node"
|
||||
// (churn 4) from "whole WM frozen" (churn 0) at a glance — the 07-26
|
||||
// frozen-anchor diagnosis took cross-referencing ISE streams by hand.
|
||||
let ch_id1: String = json_get(json_array_get(wm_top, 1), "id")
|
||||
let ch_id2: String = json_get(json_array_get(wm_top, 2), "id")
|
||||
let ch_id3: String = json_get(json_array_get(wm_top, 3), "id")
|
||||
let ch_id4: String = json_get(json_array_get(wm_top, 4), "id")
|
||||
let prev_top5: String = state_get("soul.prev_wm_top5")
|
||||
let ch0: Int = if str_eq(wm_top0_id, "") { 0 } else { if str_contains(prev_top5, wm_top0_id) { 0 } else { 1 } }
|
||||
let ch1: Int = if str_eq(ch_id1, "") { 0 } else { if str_contains(prev_top5, ch_id1) { 0 } else { 1 } }
|
||||
let ch2: Int = if str_eq(ch_id2, "") { 0 } else { if str_contains(prev_top5, ch_id2) { 0 } else { 1 } }
|
||||
let ch3: Int = if str_eq(ch_id3, "") { 0 } else { if str_contains(prev_top5, ch_id3) { 0 } else { 1 } }
|
||||
let ch4: Int = if str_eq(ch_id4, "") { 0 } else { if str_contains(prev_top5, ch_id4) { 0 } else { 1 } }
|
||||
let wm_churn: Int = ch0 + ch1 + ch2 + ch3 + ch4
|
||||
state_set("soul.prev_wm_top5", wm_top0_id + "|" + ch_id1 + "|" + ch_id2 + "|" + ch_id3 + "|" + ch_id4)
|
||||
// wm_top0_wm: the leader's weight. A frozen anchor reads as a constant
|
||||
// here; healthy rotation shows it moving with the promotion scores.
|
||||
let wm_top0_wm_raw: String = json_get(wm_top0, "wm")
|
||||
let wm_top0_wm: String = if str_eq(wm_top0_wm_raw, "") { "0" } else { wm_top0_wm_raw }
|
||||
// Activation observability (2026-07-27 self-review; cumulative since
|
||||
// 2026-07-31): counters from the runtime for the soul's own in-process
|
||||
// store. wm_evicted / breakthroughs are now MONOTONIC process-lifetime
|
||||
// totals (the old per-call values described only the LAST activate call,
|
||||
// so this 60s heartbeat missed nearly every event — curiosity alone runs
|
||||
// 2 activates per 30s between beats). We emit the cumulative totals plus
|
||||
// *_delta fields (change since the previous heartbeat, state-tracked the
|
||||
// same way as node_delta). embed_breaker_open=1 means semantic activation
|
||||
// is silently degraded to lexical-only until the Ollama circuit-breaker
|
||||
// cooldown expires — the failure mode embed_ok structurally cannot see
|
||||
// (it pings the Ollama root, not the embed pipeline).
|
||||
let act_stats: String = engram_act_stats_json()
|
||||
let act_evict_raw: String = json_get(act_stats, "wm_evicted")
|
||||
let act_evict: String = if str_eq(act_evict_raw, "") { "-1" } else { act_evict_raw }
|
||||
let act_bt_raw: String = json_get(act_stats, "breakthroughs")
|
||||
let act_bt: String = if str_eq(act_bt_raw, "") { "-1" } else { act_bt_raw }
|
||||
let evict_now: Int = if str_eq(act_evict_raw, "") { 0 - 1 } else { str_to_int(act_evict_raw) }
|
||||
let bt_now: Int = if str_eq(act_bt_raw, "") { 0 - 1 } else { str_to_int(act_bt_raw) }
|
||||
let prev_evict_raw: String = state_get("soul.prev_wm_evicted")
|
||||
let prev_evict: Int = if str_eq(prev_evict_raw, "") { 0 } else { str_to_int(prev_evict_raw) }
|
||||
let prev_bt_raw: String = state_get("soul.prev_breakthroughs")
|
||||
let prev_bt: Int = if str_eq(prev_bt_raw, "") { 0 } else { str_to_int(prev_bt_raw) }
|
||||
// Clamp deltas at 0: prev > now can only mean the counter restarted
|
||||
// (fresh process) — report the new absolute count, not a negative delta.
|
||||
let evict_delta: Int = if evict_now < 0 { 0 } else { if evict_now < prev_evict { evict_now } else { evict_now - prev_evict } }
|
||||
let bt_delta: Int = if bt_now < 0 { 0 } else { if bt_now < prev_bt { bt_now } else { bt_now - prev_bt } }
|
||||
if evict_now >= 0 { state_set("soul.prev_wm_evicted", int_to_str(evict_now)) }
|
||||
if bt_now >= 0 { state_set("soul.prev_breakthroughs", int_to_str(bt_now)) }
|
||||
// embed_eligible (2026-07-31 self-review): true denominator for embedding
|
||||
// coverage on the authoritative :8742 store. Absolute embed_count alone
|
||||
// invites the documented "~30% coverage, something is broken" misdiagnosis
|
||||
// — most nodes are ISE/Tag/short-content and permanently ineligible.
|
||||
// Real coverage = embed_count / embed_eligible. -1 = stats unreachable.
|
||||
let hb_stats: String = http_get(hb_engram_url + "/api/stats")
|
||||
let embed_elig_raw: String = json_get(hb_stats, "embed_eligible_count")
|
||||
let embed_elig: String = if str_eq(embed_elig_raw, "") { "-1" } else { embed_elig_raw }
|
||||
// auto_term_streak (2026-07-31): consecutive curiosity scans with the same
|
||||
// auto seed term — already state-tracked by proactive_curiosity; surfaced
|
||||
// here so the stuck-term failure is visible in the heartbeat stream too.
|
||||
let hb_ats_raw: String = state_get("soul.auto_term_streak")
|
||||
let hb_ats: Int = if str_eq(hb_ats_raw, "") { 0 } else { str_to_int(hb_ats_raw) }
|
||||
let act_brk_raw: String = json_get(act_stats, "embed_breaker_open")
|
||||
let act_brk: String = if str_eq(act_brk_raw, "") { "-1" } else { act_brk_raw }
|
||||
// ctx_cos (2026-07-29 self-review): cos(query, context centroid) at the
|
||||
// last activate call — the drift gauge for the new context-centroid
|
||||
// scoring. ~1.0 aligned; low at domain-rotation boundaries is healthy;
|
||||
// -2.0 pinned for hours means the centroid never initializes (embedder
|
||||
// down) and semantic continuity is silently absent.
|
||||
let ctx_cos_raw: String = json_get(act_stats, "ctx_cos")
|
||||
let ctx_cos: String = if str_eq(ctx_cos_raw, "") { "-2" } else { ctx_cos_raw }
|
||||
let payload: String = "{\"event\":\"heartbeat\",\"pulse\":" + pulse + ",\"tick\":" + pulse + ",\"boot\":" + boot + ",\"idle\":" + idle + ",\"idle_ms\":" + int_to_str(idle_ms) + ",\"node_count\":" + int_to_str(nc) + ",\"edge_count\":" + int_to_str(ec) + ",\"node_delta\":" + int_to_str(node_delta) + ",\"edge_delta\":" + int_to_str(edge_delta) + ",\"wm_active\":" + int_to_str(wmc) + ",\"wm_delta\":" + int_to_str(wm_delta) + ",\"wm_saturated\":" + int_to_str(wm_sat) + ",\"wm_top0_streak\":" + int_to_str(t0streak) + ",\"wm_churn\":" + int_to_str(wm_churn) + ",\"wm_top0_wm\":" + wm_top0_wm + ",\"sync_added_total\":" + sat_str + ",\"sync_age_ms\":" + int_to_str(sync_age) + ",\"wm_avg_weight\":" + wm_avg_str + ",\"wm_top\":" + wm_top + ",\"ts\":" + int_to_str(ts) + ",\"uptime_ms\":" + int_to_str(up_ms) + ",\"uptime\":\"" + up_human + "\",\"embed_ok\":" + int_to_str(emb_ok) + ",\"embed_backfilled\":" + bf_done + ",\"embed_count\":" + bf_total + ",\"embed_eligible\":" + embed_elig + ",\"wm_evicted\":" + act_evict + ",\"wm_evicted_delta\":" + int_to_str(evict_delta) + ",\"breakthroughs\":" + act_bt + ",\"breakthroughs_delta\":" + int_to_str(bt_delta) + ",\"auto_term_streak\":" + int_to_str(hb_ats) + ",\"embed_breaker_open\":" + act_brk + ",\"ctx_cos\":" + ctx_cos + ",\"ise_fail\":" + fail_str + "}"
|
||||
ise_post(payload)
|
||||
}
|
||||
|
||||
@@ -210,20 +338,82 @@ fn emit_heartbeat() -> Void {
|
||||
//
|
||||
// Returns true if any nodes were activated.
|
||||
// auto_term_try_slot — attempt to set cseed_auto from one WM slot.
|
||||
// Only writes to cseed_auto if node_type is Memory, BacklogItem, or Entity
|
||||
// AND the first word of the label is > 3 chars (guards bracket-prefixed labels).
|
||||
// Designed to be called in reverse slot order (highest index first) so that
|
||||
// the lowest-indexed slot (highest WM weight) wins by last-write semantics.
|
||||
// Only writes to cseed_auto if node_type is Memory, BacklogItem, Entity, or
|
||||
// Knowledge AND the first word of the label is > 3 chars (guards
|
||||
// bracket-prefixed labels). Designed to be called in reverse slot order
|
||||
// (highest index first) so that the lowest-indexed slot (highest WM weight)
|
||||
// wins by last-write semantics.
|
||||
//
|
||||
// KNOWLEDGE ADMISSION (2026-07-23 self-review): WM top-10 is now dominated by
|
||||
// Knowledge nodes (world-ingestor titles + captures), so excluding Knowledge
|
||||
// left auto_term empty on EVERY curiosity_scan since boot 6 — the dynamic
|
||||
// seeding path was dead. Knowledge labels are real titles after the
|
||||
// neuron-api label fix. Sentinel-shaped labels ("knowledge:captured",
|
||||
// "memory:remembered" — colon, no space) carry no seed signal and are
|
||||
// skipped so legacy nodes cannot seed the scan with the word "knowledge".
|
||||
fn auto_term_try_slot(slot_type: String, slot_lbl: String) -> Void {
|
||||
state_set("_ats_ok", "0")
|
||||
if str_eq(slot_type, "Memory") { state_set("_ats_ok", "1") }
|
||||
if str_eq(slot_type, "BacklogItem") { state_set("_ats_ok", "1") }
|
||||
if str_eq(slot_type, "Entity") { state_set("_ats_ok", "1") }
|
||||
if str_eq(slot_type, "Knowledge") { state_set("_ats_ok", "1") }
|
||||
if str_contains(slot_lbl, ":") {
|
||||
if !str_contains(slot_lbl, " ") { state_set("_ats_ok", "0") }
|
||||
}
|
||||
if str_eq(state_get("_ats_ok"), "1") {
|
||||
if !str_eq(slot_lbl, "") {
|
||||
let sp: Int = str_find_chars(slot_lbl, " :([")
|
||||
if sp > 3 {
|
||||
state_set("cseed_auto", str_slice(slot_lbl, 0, sp))
|
||||
// GENRE-WORD BLOCKLIST (2026-07-23 self-review): world-ingestor
|
||||
// titles open with classifier prefixes ("Method paper ...",
|
||||
// "Theory paper ..."), so the first word is a genre tag, not a
|
||||
// topic. Verified live: every scan after Knowledge admission
|
||||
// seeded on 'Method'. Skip these; a lower-WM slot with a
|
||||
// topical first word wins instead.
|
||||
let term: String = str_slice(slot_lbl, 0, sp)
|
||||
state_set("_ats_gw", "0")
|
||||
if str_eq(term, "Method") { state_set("_ats_gw", "1") }
|
||||
if str_eq(term, "Theory") { state_set("_ats_gw", "1") }
|
||||
if str_eq(term, "Finding") { state_set("_ats_gw", "1") }
|
||||
if str_eq(term, "Survey") { state_set("_ats_gw", "1") }
|
||||
if str_eq(term, "Paper") { state_set("_ats_gw", "1") }
|
||||
if str_eq(term, "Knowledge") { state_set("_ats_gw", "1") }
|
||||
if str_eq(term, "Value") { state_set("_ats_gw", "1") }
|
||||
// STOPWORD FILTER (2026-07-30 self-review): the genre
|
||||
// blocklist above was whack-a-mole — observed live seeds
|
||||
// included "What", "Colon", "Prose", "Context", "Self",
|
||||
// "Closing", "Global", "Universal": English function words
|
||||
// and document-structure words that pass the >3-char guard
|
||||
// but carry no topical signal (a first-word extractor has no
|
||||
// term-quality scoring). Single delimited membership test
|
||||
// against a curated list of function words + title/structure
|
||||
// words; topical technical terms (MemQ, AsymGRPO, Mobius,
|
||||
// engram_goal_bias) pass untouched. Both Title-case and
|
||||
// lowercase variants listed for the most common offenders.
|
||||
let stopw: String = "|What|When|Where|Which|Whose|While|This|That|These|Those|There|Their|Then|Than|With|Without|From|Into|Onto|Over|Under|About|Between|Among|Across|Some|Most|More|Less|Very|Each|Every|Both|Also|Only|Just|Does|Will|Would|Could|Should|Might|Must|Have|Been|Being|Toward|Towards|Using|Based|Upon|Here|Your|Ours|They|Them|what|this|that|with|from|context|Context|Prose|Colon|Self|Test|Testing|Closing|Global|Universal|Persona|Semantic|Spreading|Temporal|Numeric|Register|Identifying|Introduction|Overview|Summary|Section|General|Notes|Note|"
|
||||
if str_contains(stopw, "|" + term + "|") { state_set("_ats_gw", "1") }
|
||||
// QUOTED-TITLE GUARD (2026-07-25 self-review): labels that
|
||||
// open with a quote ('"The Algorithmic Caricature" ...')
|
||||
// defeat the >3-char stopword guard — the extracted term
|
||||
// '"The' is 4 chars and seeds a lexical flood on "The"
|
||||
// (observed live: activated jumped 48 → 87). Any term
|
||||
// carrying a quote character is not a topic word.
|
||||
if str_contains(term, "\"") { state_set("_ats_gw", "1") }
|
||||
if str_contains(term, "'") { state_set("_ats_gw", "1") }
|
||||
// AUTO-TERM TABU (2026-07-25 self-review): finst-style
|
||||
// inhibition-of-return (ACT-R declarative finsts: small
|
||||
// marker pool, hard exclusion). The last 4 selected auto
|
||||
// terms are ineligible (~2 min at the 30s scan cadence),
|
||||
// forcing rotation instead of "Fast-slow" every scan for
|
||||
// hours. Empty tabu slots return "" from state_get and can
|
||||
// never match — term is always > 3 chars here.
|
||||
if str_eq(term, state_get("soul.tabu_t0")) { state_set("_ats_gw", "1") }
|
||||
if str_eq(term, state_get("soul.tabu_t1")) { state_set("_ats_gw", "1") }
|
||||
if str_eq(term, state_get("soul.tabu_t2")) { state_set("_ats_gw", "1") }
|
||||
if str_eq(term, state_get("soul.tabu_t3")) { state_set("_ats_gw", "1") }
|
||||
if str_eq(state_get("_ats_gw"), "0") {
|
||||
state_set("cseed_auto", term)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -280,11 +470,11 @@ fn proactive_curiosity() -> Bool {
|
||||
// loop. A single phrase activation matches few (often zero) nodes lexically;
|
||||
// small counts here are the point, not a regression. hops=1 as before.
|
||||
//
|
||||
// NOTE: a semantic seed supplement (cosine sim ≥ 0.70 scan over embedded nodes)
|
||||
// was planned alongside hops=1 but is NOT yet implemented — embed_ok in
|
||||
// heartbeats confirms Ollama is reachable, but no embedding call is made during
|
||||
// activation. The seed-finding loop in el_runtime.c uses istr_contains only.
|
||||
// (2026-06-30 self-review: corrected stale comment)
|
||||
// NOTE (2026-07-31 self-review): semantic seeding/gating IS implemented in
|
||||
// engram_activate (el_runtime.c): the query is embedded, top-K cosine
|
||||
// matches supplement the lexical istr_contains seeds, cosine gates
|
||||
// propagation, and a semantic term feeds the WM promotion score. Lexical
|
||||
// matching is the fallback when the embedder/breaker is unavailable.
|
||||
let curiosity_seed: String = curiosity_term_a + " " + curiosity_term_b + " " + curiosity_term_c
|
||||
let results_all: String = engram_activate_json(curiosity_seed, 1)
|
||||
let found: Int = json_array_len(results_all)
|
||||
@@ -293,8 +483,19 @@ fn proactive_curiosity() -> Bool {
|
||||
// pattern as attend(): json_array_get element 0, json_get its "id".
|
||||
let top_entry: String = json_array_get(results_all, 0)
|
||||
let top_id: String = json_get(top_entry, "id")
|
||||
// STREAK-GATED STRENGTHEN (2026-07-25 self-review): unconditionally
|
||||
// strengthening the top result every scan was a positive-feedback fixed
|
||||
// point — whatever led WM got its salience bumped again, kept leading,
|
||||
// and pinned the auto_term for hours ("Fast-slow" era). Strengthen only
|
||||
// when the top node CHANGED since the last scan: novelty is reinforced,
|
||||
// incumbency is not. Pairs with the runtime-side Lebiere-Best short-term
|
||||
// inhibition (el_runtime.c Pass 2), which handles score-level rotation.
|
||||
let prev_str_id: String = state_get("soul.last_strengthen_id")
|
||||
if !str_eq(top_id, "") {
|
||||
engram_strengthen(top_id)
|
||||
if !str_eq(top_id, prev_str_id) {
|
||||
engram_strengthen(top_id)
|
||||
}
|
||||
state_set("soul.last_strengthen_id", top_id)
|
||||
}
|
||||
|
||||
// WM-autobiographical 4th seed: scan top-10 WM nodes for the highest-ranked
|
||||
@@ -342,6 +543,21 @@ fn proactive_curiosity() -> Bool {
|
||||
let found_auto: Int = json_array_len(results_auto)
|
||||
let total_found: Int = found + found_auto
|
||||
let safe_auto: String = str_replace(auto_term, "\"", "'")
|
||||
// Push the selected term into the 4-deep tabu ring (see
|
||||
// auto_term_try_slot) and track the consecutive-same-term streak for
|
||||
// the ISE — the stuck-term failure becomes a one-glance signal.
|
||||
let prev_auto: String = state_get("soul.prev_auto_term")
|
||||
let atstreak_raw: String = state_get("soul.auto_term_streak")
|
||||
let atstreak_prev: Int = if str_eq(atstreak_raw, "") { 0 } else { str_to_int(atstreak_raw) }
|
||||
let atstreak: Int = if str_eq(auto_term, prev_auto) { atstreak_prev + 1 } else { 1 }
|
||||
state_set("soul.prev_auto_term", auto_term)
|
||||
state_set("soul.auto_term_streak", int_to_str(atstreak))
|
||||
if !str_eq(auto_term, "") {
|
||||
state_set("soul.tabu_t3", state_get("soul.tabu_t2"))
|
||||
state_set("soul.tabu_t2", state_get("soul.tabu_t1"))
|
||||
state_set("soul.tabu_t1", state_get("soul.tabu_t0"))
|
||||
state_set("soul.tabu_t0", auto_term)
|
||||
}
|
||||
|
||||
let wmc: Int = engram_wm_count()
|
||||
// wm_top snapshot in curiosity_scan ISE: top-3 WM nodes by weight.
|
||||
@@ -354,7 +570,8 @@ fn proactive_curiosity() -> Bool {
|
||||
let wm3: String = engram_wm_top_json(3)
|
||||
let ise: String = "{\"event\":\"curiosity_scan\",\"seed\":\"" + curiosity_seed
|
||||
+ "\",\"auto_term\":\"" + safe_auto
|
||||
+ "\",\"minute_block\":" + int_to_str(minute_block)
|
||||
+ "\",\"auto_term_streak\":" + int_to_str(atstreak)
|
||||
+ ",\"minute_block\":" + int_to_str(minute_block)
|
||||
+ ",\"activated\":" + int_to_str(total_found)
|
||||
+ ",\"wm_active\":" + int_to_str(wmc)
|
||||
+ ",\"wm_top\":" + wm3
|
||||
@@ -633,6 +850,17 @@ fn awareness_run() -> Void {
|
||||
let tick_mark: Any = el_arena_push()
|
||||
let running: String = state_get("soul.running")
|
||||
if str_eq(running, "false") {
|
||||
// Shutdown ISE (2026-07-28 self-review): graceful exit was invisible
|
||||
// in the ISE stream — indistinguishable from a crash or a frozen
|
||||
// loop. Emit a final event with uptime/pulse so the stream records
|
||||
// how this boot ended. (Covers state-driven shutdown only; SIGKILL
|
||||
// still leaves no trace — that absence is itself the crash signal.)
|
||||
let sd_boot_raw: String = state_get("soul_boot_count")
|
||||
let sd_boot: String = if str_eq(sd_boot_raw, "") { "0" } else { sd_boot_raw }
|
||||
ise_post("{\"event\":\"shutdown\",\"boot\":" + sd_boot
|
||||
+ ",\"pulse\":" + int_to_str(pulse_count())
|
||||
+ ",\"uptime_ms\":" + int_to_str(elapsed_ms())
|
||||
+ ",\"ts\":" + int_to_str(time_now()) + "}")
|
||||
println("[awareness] exiting")
|
||||
el_arena_pop(tick_mark)
|
||||
return ""
|
||||
@@ -703,15 +931,29 @@ fn awareness_run() -> Void {
|
||||
let engram_url: String = if str_eq(sync_state_url, "") { "http://localhost:8742" } else { sync_state_url }
|
||||
if !str_eq(engram_url, "") {
|
||||
let sync_json: String = http_get(engram_url + "/api/sync")
|
||||
if !str_eq(sync_json, "") && !str_eq(sync_json, "{}") {
|
||||
let sync_ok: Bool = !str_eq(sync_json, "") && !str_eq(sync_json, "{}")
|
||||
// Empty-sync warn ISE (2026-07-28 self-review): an empty/{} sync
|
||||
// response was silently skipped, making "engram unreachable for
|
||||
// hours" look identical to "quiet but healthy" — the exact
|
||||
// failure class the URL-fallback comment above fights. One warn
|
||||
// event per refresh interval (10 min default) is cheap and makes
|
||||
// a persistently-failing sync visible in the stream itself.
|
||||
if !sync_ok {
|
||||
ise_post("{\"event\":\"sync_empty\",\"ts\":" + int_to_str(time_now()) + "}")
|
||||
}
|
||||
if sync_ok {
|
||||
let cgi_id: String = state_get("soul_cgi_id")
|
||||
let tmp: String = "/tmp/soul-sync-" + cgi_id + ".json"
|
||||
fs_write(tmp, sync_json)
|
||||
let added: Int = engram_load_merge(tmp)
|
||||
// Backflow control: the merged snapshot carries ISE telemetry
|
||||
// from the HTTP store. Prune anything older than 48h — same
|
||||
// horizon the HTTP store itself uses (server.el ISE insert).
|
||||
let pruned_sync: Int = engram_prune_telemetry(172800000)
|
||||
// from the HTTP store. Prune on the same horizon the HTTP
|
||||
// store itself uses — read ENGRAM_ISE_RETENTION_MS (the env
|
||||
// server.el honors) instead of duplicating the 48h magic
|
||||
// number, so the two stores can't drift. (2026-07-28)
|
||||
let ret_raw: String = env("ENGRAM_ISE_RETENTION_MS")
|
||||
let ret_ms: Int = if str_eq(ret_raw, "") { 172800000 } else { str_to_int(ret_raw) }
|
||||
let pruned_sync: Int = engram_prune_telemetry(ret_ms)
|
||||
// Running total of merged-in nodes this boot, surfaced in the
|
||||
// heartbeat ISE as sync_added_total (same state mechanism as
|
||||
// the pulse counter).
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// auto-generated by elc --emit-header — do not edit
|
||||
// auto-generated by elc --emit-header - do not edit
|
||||
extern fn chat_default_model() -> String
|
||||
extern fn engram_numeric_valid(s: String) -> Bool
|
||||
extern fn parse_float_x100(s: String) -> Int
|
||||
@@ -16,18 +16,35 @@ extern fn engram_nodes_merge(a: String, b: String) -> String
|
||||
extern fn id_in_seen(node_id: String, seen: String) -> Bool
|
||||
extern fn add_to_seen(seen: String, node_id: String) -> String
|
||||
extern fn engram_extract_ids(nodes_json: String) -> String
|
||||
extern fn affective_node_ts(node_json: String) -> Int
|
||||
extern fn engram_compile(intent: String) -> String
|
||||
extern fn distill_transcript(transcript: String) -> String
|
||||
extern fn json_safe(s: String) -> String
|
||||
extern fn current_engine_note(model: String) -> String
|
||||
extern fn bounded_persona_floor() -> String
|
||||
extern fn operator_identity_block() -> String
|
||||
extern fn build_system_prompt(ctx: String, chat_mode: Bool) -> String
|
||||
extern fn hist_append(hist: String, role: String, content: String) -> String
|
||||
extern fn conv_hist_key(session_id: String) -> String
|
||||
extern fn conv_hist_label(session_id: String) -> String
|
||||
extern fn is_utility_request(body: String, session_id: String) -> Bool
|
||||
extern fn provenance_scan_urls(arr: String, acc: String) -> String
|
||||
extern fn provenance_add_sources(block: String, btype: String, has_cit: Bool, cit_raw: String, acc: String) -> String
|
||||
extern fn provenance_names(tools_used: String) -> String
|
||||
extern fn text_join_sep(accumulated: String, incoming: String, after_interruption: Bool) -> String
|
||||
extern fn receipt_rule() -> String
|
||||
extern fn receipt_strip(s: String) -> String
|
||||
extern fn tool_receipt(tools_used: String, sources: String) -> String
|
||||
extern fn hist_trim(hist: String) -> String
|
||||
extern fn hist_trim_with_bell_guard(hist: String) -> String
|
||||
extern fn clean_llm_response(s: String) -> String
|
||||
extern fn conv_history_persist(hist: String) -> Void
|
||||
extern fn conv_history_load() -> String
|
||||
extern fn conv_history_persist(session_id: String, hist: String) -> Void
|
||||
extern fn conv_history_load(session_id: String) -> String
|
||||
extern fn conv_history_record(session_id: String, user_msg: String, assistant_msg: String, receipt: String) -> Void
|
||||
extern fn conv_history_block(session_id: String) -> String
|
||||
extern fn layered_generate(prompt: String, imprint_id: String, session_id: String) -> String
|
||||
extern fn session_preload_bullets(nodes: String, max_bullets: Int, snip_len: Int) -> String
|
||||
extern fn affective_context_prefix() -> String
|
||||
extern fn handle_chat(body: String) -> String
|
||||
extern fn handle_see(body: String) -> String
|
||||
extern fn studio_tools_json() -> String
|
||||
@@ -37,6 +54,8 @@ extern fn llm_wire_format() -> String
|
||||
extern fn json_escape(s: String) -> String
|
||||
extern fn openai_chat_complete(model: String, base_url: String, api_key: String, safe_sys: String, messages_json: String) -> String
|
||||
extern fn agentic_tools_literal() -> String
|
||||
extern fn web_search_tool_json() -> String
|
||||
extern fn strip_client_web_search(tools_inner: String) -> String
|
||||
extern fn agentic_tools_with_web() -> String
|
||||
extern fn connector_tools_json() -> String
|
||||
extern fn agentic_tools_all() -> String
|
||||
@@ -46,6 +65,10 @@ extern fn call_neuron_mcp(tool_name: String, args: String) -> String
|
||||
extern fn agent_workspace_root() -> String
|
||||
extern fn path_within_root(path: String, root: String) -> Bool
|
||||
extern fn resolve_in_root(path: String, root: String) -> String
|
||||
extern fn run_command_is_readonly(cmd: String) -> Bool
|
||||
extern fn cmd_abs_escape_at(cmd: String, root: String, needle: String) -> Bool
|
||||
extern fn run_command_guard(cmd: String, root: String) -> String
|
||||
extern fn classify_tool_risk(tool_name: String, tool_input: String) -> String
|
||||
extern fn dispatch_tool(tool_name: String, tool_input: String) -> String
|
||||
extern fn is_builtin_tool(tool_name: String) -> Bool
|
||||
extern fn next_bridge_id() -> String
|
||||
|
||||
+221
-73
@@ -133,6 +133,8 @@ el_val_t emit_heartbeat(void) {
|
||||
el_val_t boot = ({ el_val_t _if_result_4 = 0; if (str_eq(boot_raw, EL_STR(""))) { _if_result_4 = (EL_STR("0")); } else { _if_result_4 = (boot_raw); } _if_result_4; });
|
||||
el_val_t idle = int_to_str(idle_count());
|
||||
el_val_t ts = time_now();
|
||||
el_val_t last_act_raw = state_get(EL_STR("soul.last_activity_ts"));
|
||||
el_val_t idle_ms = ({ el_val_t _if_result_5 = 0; if (str_eq(last_act_raw, EL_STR(""))) { _if_result_5 = ((0 - 1)); } else { _if_result_5 = ((ts - str_to_int(last_act_raw))); } _if_result_5; });
|
||||
el_val_t nc = engram_node_count();
|
||||
el_val_t ec = engram_edge_count();
|
||||
el_val_t wmc = engram_wm_count();
|
||||
@@ -143,24 +145,90 @@ el_val_t emit_heartbeat(void) {
|
||||
el_val_t up_human = elapsed_human();
|
||||
el_val_t emb_ok = embed_ok();
|
||||
el_val_t fail_raw = state_get(EL_STR("soul.ise_fail_count"));
|
||||
el_val_t fail_str = ({ el_val_t _if_result_5 = 0; if (str_eq(fail_raw, EL_STR(""))) { _if_result_5 = (EL_STR("0")); } else { _if_result_5 = (fail_raw); } _if_result_5; });
|
||||
el_val_t fail_str = ({ el_val_t _if_result_6 = 0; if (str_eq(fail_raw, EL_STR(""))) { _if_result_6 = (EL_STR("0")); } else { _if_result_6 = (fail_raw); } _if_result_6; });
|
||||
el_val_t sat_raw = state_get(EL_STR("soul.sync_added_total"));
|
||||
el_val_t sat_str = ({ el_val_t _if_result_6 = 0; if (str_eq(sat_raw, EL_STR(""))) { _if_result_6 = (EL_STR("0")); } else { _if_result_6 = (sat_raw); } _if_result_6; });
|
||||
el_val_t sat_str = ({ el_val_t _if_result_7 = 0; if (str_eq(sat_raw, EL_STR(""))) { _if_result_7 = (EL_STR("0")); } else { _if_result_7 = (sat_raw); } _if_result_7; });
|
||||
el_val_t prev_wm_raw = state_get(EL_STR("soul.prev_wm_active"));
|
||||
el_val_t prev_wm = ({ el_val_t _if_result_7 = 0; if (str_eq(prev_wm_raw, EL_STR(""))) { _if_result_7 = (0); } else { _if_result_7 = (str_to_int(prev_wm_raw)); } _if_result_7; });
|
||||
el_val_t prev_wm = ({ el_val_t _if_result_8 = 0; if (str_eq(prev_wm_raw, EL_STR(""))) { _if_result_8 = (0); } else { _if_result_8 = (str_to_int(prev_wm_raw)); } _if_result_8; });
|
||||
el_val_t wm_delta = (wmc - prev_wm);
|
||||
state_set(EL_STR("soul.prev_wm_active"), int_to_str(wmc));
|
||||
el_val_t prev_nc_raw = state_get(EL_STR("soul.prev_node_count"));
|
||||
el_val_t prev_nc = ({ el_val_t _if_result_8 = 0; if (str_eq(prev_nc_raw, EL_STR(""))) { _if_result_8 = (nc); } else { _if_result_8 = (str_to_int(prev_nc_raw)); } _if_result_8; });
|
||||
el_val_t prev_nc = ({ el_val_t _if_result_9 = 0; if (str_eq(prev_nc_raw, EL_STR(""))) { _if_result_9 = (nc); } else { _if_result_9 = (str_to_int(prev_nc_raw)); } _if_result_9; });
|
||||
el_val_t node_delta = (nc - prev_nc);
|
||||
state_set(EL_STR("soul.prev_node_count"), int_to_str(nc));
|
||||
el_val_t prev_ec_raw = state_get(EL_STR("soul.prev_edge_count"));
|
||||
el_val_t prev_ec = ({ el_val_t _if_result_9 = 0; if (str_eq(prev_ec_raw, EL_STR(""))) { _if_result_9 = (ec); } else { _if_result_9 = (str_to_int(prev_ec_raw)); } _if_result_9; });
|
||||
el_val_t prev_ec = ({ el_val_t _if_result_10 = 0; if (str_eq(prev_ec_raw, EL_STR(""))) { _if_result_10 = (ec); } else { _if_result_10 = (str_to_int(prev_ec_raw)); } _if_result_10; });
|
||||
el_val_t edge_delta = (ec - prev_ec);
|
||||
state_set(EL_STR("soul.prev_edge_count"), int_to_str(ec));
|
||||
el_val_t sync_ok_raw = state_get(EL_STR("soul.last_sync_ok_ts"));
|
||||
el_val_t sync_age = ({ el_val_t _if_result_10 = 0; if (str_eq(sync_ok_raw, EL_STR(""))) { _if_result_10 = ((0 - 1)); } else { _if_result_10 = ((ts - str_to_int(sync_ok_raw))); } _if_result_10; });
|
||||
el_val_t payload = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"event\":\"heartbeat\",\"pulse\":"), pulse), EL_STR(",\"tick\":")), pulse), EL_STR(",\"boot\":")), boot), EL_STR(",\"idle\":")), idle), EL_STR(",\"node_count\":")), int_to_str(nc)), EL_STR(",\"edge_count\":")), int_to_str(ec)), EL_STR(",\"node_delta\":")), int_to_str(node_delta)), EL_STR(",\"edge_delta\":")), int_to_str(edge_delta)), EL_STR(",\"wm_active\":")), int_to_str(wmc)), EL_STR(",\"wm_delta\":")), int_to_str(wm_delta)), EL_STR(",\"sync_added_total\":")), sat_str), EL_STR(",\"sync_age_ms\":")), int_to_str(sync_age)), EL_STR(",\"wm_avg_weight\":")), wm_avg_str), EL_STR(",\"wm_top\":")), wm_top), EL_STR(",\"ts\":")), int_to_str(ts)), EL_STR(",\"uptime_ms\":")), int_to_str(up_ms)), EL_STR(",\"uptime\":\"")), up_human), EL_STR("\",\"embed_ok\":")), int_to_str(emb_ok)), EL_STR(",\"ise_fail\":")), fail_str), EL_STR("}"));
|
||||
el_val_t sync_age = ({ el_val_t _if_result_11 = 0; if (str_eq(sync_ok_raw, EL_STR(""))) { _if_result_11 = ((0 - 1)); } else { _if_result_11 = ((ts - str_to_int(sync_ok_raw))); } _if_result_11; });
|
||||
el_val_t hb_env_url = env(EL_STR("SOUL_ISE_URL"));
|
||||
el_val_t hb_state_url = ({ el_val_t _if_result_12 = 0; if (str_eq(hb_env_url, EL_STR(""))) { _if_result_12 = (state_get(EL_STR("soul_engram_url"))); } else { _if_result_12 = (hb_env_url); } _if_result_12; });
|
||||
el_val_t hb_engram_url = ({ el_val_t _if_result_13 = 0; if (str_eq(hb_state_url, EL_STR(""))) { _if_result_13 = (EL_STR("http://localhost:8742")); } else { _if_result_13 = (hb_state_url); } _if_result_13; });
|
||||
el_val_t bf_resp = http_get(el_str_concat(hb_engram_url, EL_STR("/api/embed-backfill?n=32")));
|
||||
el_val_t bf_done_raw = json_get(bf_resp, EL_STR("embedded"));
|
||||
el_val_t bf_done = ({ el_val_t _if_result_14 = 0; if (str_eq(bf_done_raw, EL_STR(""))) { _if_result_14 = (EL_STR("-1")); } else { _if_result_14 = (bf_done_raw); } _if_result_14; });
|
||||
el_val_t bf_total_raw = json_get(bf_resp, EL_STR("embedded_count"));
|
||||
el_val_t bf_total = ({ el_val_t _if_result_15 = 0; if (str_eq(bf_total_raw, EL_STR(""))) { _if_result_15 = (EL_STR("-1")); } else { _if_result_15 = (bf_total_raw); } _if_result_15; });
|
||||
el_val_t wm_sat = ({ el_val_t _if_result_16 = 0; if ((wmc >= 24)) { _if_result_16 = (1); } else { _if_result_16 = (0); } _if_result_16; });
|
||||
el_val_t prev_sat_raw = state_get(EL_STR("soul.prev_wm_saturated"));
|
||||
el_val_t prev_sat = ({ el_val_t _if_result_17 = 0; if (str_eq(prev_sat_raw, EL_STR(""))) { _if_result_17 = (wm_sat); } else { _if_result_17 = (str_to_int(prev_sat_raw)); } _if_result_17; });
|
||||
if (wm_sat != prev_sat) {
|
||||
el_val_t sat_dir = ({ el_val_t _if_result_18 = 0; if ((wm_sat == 1)) { _if_result_18 = (EL_STR("onset")); } else { _if_result_18 = (EL_STR("release")); } _if_result_18; });
|
||||
ise_post(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"event\":\"wm_saturation_transition\",\"direction\":\""), sat_dir), EL_STR("\",\"wm_active\":")), int_to_str(wmc)), EL_STR(",\"wm_top\":")), wm_top), EL_STR(",\"ts\":")), int_to_str(ts)), EL_STR("}")));
|
||||
}
|
||||
state_set(EL_STR("soul.prev_wm_saturated"), int_to_str(wm_sat));
|
||||
el_val_t wm_top0 = json_array_get(wm_top, 0);
|
||||
el_val_t wm_top0_id = json_get(wm_top0, EL_STR("id"));
|
||||
el_val_t prev_top0 = state_get(EL_STR("soul.prev_wm_top0"));
|
||||
el_val_t t0streak_raw = state_get(EL_STR("soul.wm_top0_streak"));
|
||||
el_val_t t0streak_prev = ({ el_val_t _if_result_19 = 0; if (str_eq(t0streak_raw, EL_STR(""))) { _if_result_19 = (0); } else { _if_result_19 = (str_to_int(t0streak_raw)); } _if_result_19; });
|
||||
el_val_t t0streak = ({ el_val_t _if_result_20 = 0; if (str_eq(wm_top0_id, EL_STR(""))) { _if_result_20 = (0); } else { _if_result_20 = (({ el_val_t _if_result_21 = 0; if (str_eq(wm_top0_id, prev_top0)) { _if_result_21 = ((t0streak_prev + 1)); } else { _if_result_21 = (1); } _if_result_21; })); } _if_result_20; });
|
||||
state_set(EL_STR("soul.prev_wm_top0"), wm_top0_id);
|
||||
state_set(EL_STR("soul.wm_top0_streak"), int_to_str(t0streak));
|
||||
el_val_t ch_id1 = json_get(json_array_get(wm_top, 1), EL_STR("id"));
|
||||
el_val_t ch_id2 = json_get(json_array_get(wm_top, 2), EL_STR("id"));
|
||||
el_val_t ch_id3 = json_get(json_array_get(wm_top, 3), EL_STR("id"));
|
||||
el_val_t ch_id4 = json_get(json_array_get(wm_top, 4), EL_STR("id"));
|
||||
el_val_t prev_top5 = state_get(EL_STR("soul.prev_wm_top5"));
|
||||
el_val_t ch0 = ({ el_val_t _if_result_22 = 0; if (str_eq(wm_top0_id, EL_STR(""))) { _if_result_22 = (0); } else { _if_result_22 = (({ el_val_t _if_result_23 = 0; if (str_contains(prev_top5, wm_top0_id)) { _if_result_23 = (0); } else { _if_result_23 = (1); } _if_result_23; })); } _if_result_22; });
|
||||
el_val_t ch1 = ({ el_val_t _if_result_24 = 0; if (str_eq(ch_id1, EL_STR(""))) { _if_result_24 = (0); } else { _if_result_24 = (({ el_val_t _if_result_25 = 0; if (str_contains(prev_top5, ch_id1)) { _if_result_25 = (0); } else { _if_result_25 = (1); } _if_result_25; })); } _if_result_24; });
|
||||
el_val_t ch2 = ({ el_val_t _if_result_26 = 0; if (str_eq(ch_id2, EL_STR(""))) { _if_result_26 = (0); } else { _if_result_26 = (({ el_val_t _if_result_27 = 0; if (str_contains(prev_top5, ch_id2)) { _if_result_27 = (0); } else { _if_result_27 = (1); } _if_result_27; })); } _if_result_26; });
|
||||
el_val_t ch3 = ({ el_val_t _if_result_28 = 0; if (str_eq(ch_id3, EL_STR(""))) { _if_result_28 = (0); } else { _if_result_28 = (({ el_val_t _if_result_29 = 0; if (str_contains(prev_top5, ch_id3)) { _if_result_29 = (0); } else { _if_result_29 = (1); } _if_result_29; })); } _if_result_28; });
|
||||
el_val_t ch4 = ({ el_val_t _if_result_30 = 0; if (str_eq(ch_id4, EL_STR(""))) { _if_result_30 = (0); } else { _if_result_30 = (({ el_val_t _if_result_31 = 0; if (str_contains(prev_top5, ch_id4)) { _if_result_31 = (0); } else { _if_result_31 = (1); } _if_result_31; })); } _if_result_30; });
|
||||
el_val_t wm_churn = ((((ch0 + ch1) + ch2) + ch3) + ch4);
|
||||
state_set(EL_STR("soul.prev_wm_top5"), el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(wm_top0_id, EL_STR("|")), ch_id1), EL_STR("|")), ch_id2), EL_STR("|")), ch_id3), EL_STR("|")), ch_id4));
|
||||
el_val_t wm_top0_wm_raw = json_get(wm_top0, EL_STR("wm"));
|
||||
el_val_t wm_top0_wm = ({ el_val_t _if_result_32 = 0; if (str_eq(wm_top0_wm_raw, EL_STR(""))) { _if_result_32 = (EL_STR("0")); } else { _if_result_32 = (wm_top0_wm_raw); } _if_result_32; });
|
||||
el_val_t act_stats = engram_act_stats_json();
|
||||
el_val_t act_evict_raw = json_get(act_stats, EL_STR("wm_evicted"));
|
||||
el_val_t act_evict = ({ el_val_t _if_result_33 = 0; if (str_eq(act_evict_raw, EL_STR(""))) { _if_result_33 = (EL_STR("-1")); } else { _if_result_33 = (act_evict_raw); } _if_result_33; });
|
||||
el_val_t act_bt_raw = json_get(act_stats, EL_STR("breakthroughs"));
|
||||
el_val_t act_bt = ({ el_val_t _if_result_34 = 0; if (str_eq(act_bt_raw, EL_STR(""))) { _if_result_34 = (EL_STR("-1")); } else { _if_result_34 = (act_bt_raw); } _if_result_34; });
|
||||
el_val_t evict_now = ({ el_val_t _if_result_35 = 0; if (str_eq(act_evict_raw, EL_STR(""))) { _if_result_35 = ((0 - 1)); } else { _if_result_35 = (str_to_int(act_evict_raw)); } _if_result_35; });
|
||||
el_val_t bt_now = ({ el_val_t _if_result_36 = 0; if (str_eq(act_bt_raw, EL_STR(""))) { _if_result_36 = ((0 - 1)); } else { _if_result_36 = (str_to_int(act_bt_raw)); } _if_result_36; });
|
||||
el_val_t prev_evict_raw = state_get(EL_STR("soul.prev_wm_evicted"));
|
||||
el_val_t prev_evict = ({ el_val_t _if_result_37 = 0; if (str_eq(prev_evict_raw, EL_STR(""))) { _if_result_37 = (0); } else { _if_result_37 = (str_to_int(prev_evict_raw)); } _if_result_37; });
|
||||
el_val_t prev_bt_raw = state_get(EL_STR("soul.prev_breakthroughs"));
|
||||
el_val_t prev_bt = ({ el_val_t _if_result_38 = 0; if (str_eq(prev_bt_raw, EL_STR(""))) { _if_result_38 = (0); } else { _if_result_38 = (str_to_int(prev_bt_raw)); } _if_result_38; });
|
||||
el_val_t evict_delta = ({ el_val_t _if_result_39 = 0; if ((evict_now < 0)) { _if_result_39 = (0); } else { _if_result_39 = (({ el_val_t _if_result_40 = 0; if ((evict_now < prev_evict)) { _if_result_40 = (evict_now); } else { _if_result_40 = ((evict_now - prev_evict)); } _if_result_40; })); } _if_result_39; });
|
||||
el_val_t bt_delta = ({ el_val_t _if_result_41 = 0; if ((bt_now < 0)) { _if_result_41 = (0); } else { _if_result_41 = (({ el_val_t _if_result_42 = 0; if ((bt_now < prev_bt)) { _if_result_42 = (bt_now); } else { _if_result_42 = ((bt_now - prev_bt)); } _if_result_42; })); } _if_result_41; });
|
||||
if (evict_now >= 0) {
|
||||
state_set(EL_STR("soul.prev_wm_evicted"), int_to_str(evict_now));
|
||||
}
|
||||
if (bt_now >= 0) {
|
||||
state_set(EL_STR("soul.prev_breakthroughs"), int_to_str(bt_now));
|
||||
}
|
||||
el_val_t hb_stats = http_get(el_str_concat(hb_engram_url, EL_STR("/api/stats")));
|
||||
el_val_t embed_elig_raw = json_get(hb_stats, EL_STR("embed_eligible_count"));
|
||||
el_val_t embed_elig = ({ el_val_t _if_result_43 = 0; if (str_eq(embed_elig_raw, EL_STR(""))) { _if_result_43 = (EL_STR("-1")); } else { _if_result_43 = (embed_elig_raw); } _if_result_43; });
|
||||
el_val_t hb_ats_raw = state_get(EL_STR("soul.auto_term_streak"));
|
||||
el_val_t hb_ats = ({ el_val_t _if_result_44 = 0; if (str_eq(hb_ats_raw, EL_STR(""))) { _if_result_44 = (0); } else { _if_result_44 = (str_to_int(hb_ats_raw)); } _if_result_44; });
|
||||
el_val_t act_brk_raw = json_get(act_stats, EL_STR("embed_breaker_open"));
|
||||
el_val_t act_brk = ({ el_val_t _if_result_45 = 0; if (str_eq(act_brk_raw, EL_STR(""))) { _if_result_45 = (EL_STR("-1")); } else { _if_result_45 = (act_brk_raw); } _if_result_45; });
|
||||
el_val_t ctx_cos_raw = json_get(act_stats, EL_STR("ctx_cos"));
|
||||
el_val_t ctx_cos = ({ el_val_t _if_result_46 = 0; if (str_eq(ctx_cos_raw, EL_STR(""))) { _if_result_46 = (EL_STR("-2")); } else { _if_result_46 = (ctx_cos_raw); } _if_result_46; });
|
||||
el_val_t payload = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"event\":\"heartbeat\",\"pulse\":"), pulse), EL_STR(",\"tick\":")), pulse), EL_STR(",\"boot\":")), boot), EL_STR(",\"idle\":")), idle), EL_STR(",\"idle_ms\":")), int_to_str(idle_ms)), EL_STR(",\"node_count\":")), int_to_str(nc)), EL_STR(",\"edge_count\":")), int_to_str(ec)), EL_STR(",\"node_delta\":")), int_to_str(node_delta)), EL_STR(",\"edge_delta\":")), int_to_str(edge_delta)), EL_STR(",\"wm_active\":")), int_to_str(wmc)), EL_STR(",\"wm_delta\":")), int_to_str(wm_delta)), EL_STR(",\"wm_saturated\":")), int_to_str(wm_sat)), EL_STR(",\"wm_top0_streak\":")), int_to_str(t0streak)), EL_STR(",\"wm_churn\":")), int_to_str(wm_churn)), EL_STR(",\"wm_top0_wm\":")), wm_top0_wm), EL_STR(",\"sync_added_total\":")), sat_str), EL_STR(",\"sync_age_ms\":")), int_to_str(sync_age)), EL_STR(",\"wm_avg_weight\":")), wm_avg_str), EL_STR(",\"wm_top\":")), wm_top), EL_STR(",\"ts\":")), int_to_str(ts)), EL_STR(",\"uptime_ms\":")), int_to_str(up_ms)), EL_STR(",\"uptime\":\"")), up_human), EL_STR("\",\"embed_ok\":")), int_to_str(emb_ok)), EL_STR(",\"embed_backfilled\":")), bf_done), EL_STR(",\"embed_count\":")), bf_total), EL_STR(",\"embed_eligible\":")), embed_elig), EL_STR(",\"wm_evicted\":")), act_evict), EL_STR(",\"wm_evicted_delta\":")), int_to_str(evict_delta)), EL_STR(",\"breakthroughs\":")), act_bt), EL_STR(",\"breakthroughs_delta\":")), int_to_str(bt_delta)), EL_STR(",\"auto_term_streak\":")), int_to_str(hb_ats)), EL_STR(",\"embed_breaker_open\":")), act_brk), EL_STR(",\"ctx_cos\":")), ctx_cos), EL_STR(",\"ise_fail\":")), fail_str), EL_STR("}"));
|
||||
ise_post(payload);
|
||||
return 0;
|
||||
}
|
||||
@@ -176,11 +244,66 @@ el_val_t auto_term_try_slot(el_val_t slot_type, el_val_t slot_lbl) {
|
||||
if (str_eq(slot_type, EL_STR("Entity"))) {
|
||||
state_set(EL_STR("_ats_ok"), EL_STR("1"));
|
||||
}
|
||||
if (str_eq(slot_type, EL_STR("Knowledge"))) {
|
||||
state_set(EL_STR("_ats_ok"), EL_STR("1"));
|
||||
}
|
||||
if (str_contains(slot_lbl, EL_STR(":"))) {
|
||||
if (!str_contains(slot_lbl, EL_STR(" "))) {
|
||||
state_set(EL_STR("_ats_ok"), EL_STR("0"));
|
||||
}
|
||||
}
|
||||
if (str_eq(state_get(EL_STR("_ats_ok")), EL_STR("1"))) {
|
||||
if (!str_eq(slot_lbl, EL_STR(""))) {
|
||||
el_val_t sp = str_find_chars(slot_lbl, EL_STR(" :(["));
|
||||
if (sp > 3) {
|
||||
state_set(EL_STR("cseed_auto"), str_slice(slot_lbl, 0, sp));
|
||||
el_val_t term = str_slice(slot_lbl, 0, sp);
|
||||
state_set(EL_STR("_ats_gw"), EL_STR("0"));
|
||||
if (str_eq(term, EL_STR("Method"))) {
|
||||
state_set(EL_STR("_ats_gw"), EL_STR("1"));
|
||||
}
|
||||
if (str_eq(term, EL_STR("Theory"))) {
|
||||
state_set(EL_STR("_ats_gw"), EL_STR("1"));
|
||||
}
|
||||
if (str_eq(term, EL_STR("Finding"))) {
|
||||
state_set(EL_STR("_ats_gw"), EL_STR("1"));
|
||||
}
|
||||
if (str_eq(term, EL_STR("Survey"))) {
|
||||
state_set(EL_STR("_ats_gw"), EL_STR("1"));
|
||||
}
|
||||
if (str_eq(term, EL_STR("Paper"))) {
|
||||
state_set(EL_STR("_ats_gw"), EL_STR("1"));
|
||||
}
|
||||
if (str_eq(term, EL_STR("Knowledge"))) {
|
||||
state_set(EL_STR("_ats_gw"), EL_STR("1"));
|
||||
}
|
||||
if (str_eq(term, EL_STR("Value"))) {
|
||||
state_set(EL_STR("_ats_gw"), EL_STR("1"));
|
||||
}
|
||||
el_val_t stopw = EL_STR("|What|When|Where|Which|Whose|While|This|That|These|Those|There|Their|Then|Than|With|Without|From|Into|Onto|Over|Under|About|Between|Among|Across|Some|Most|More|Less|Very|Each|Every|Both|Also|Only|Just|Does|Will|Would|Could|Should|Might|Must|Have|Been|Being|Toward|Towards|Using|Based|Upon|Here|Your|Ours|They|Them|what|this|that|with|from|context|Context|Prose|Colon|Self|Test|Testing|Closing|Global|Universal|Persona|Semantic|Spreading|Temporal|Numeric|Register|Identifying|Introduction|Overview|Summary|Section|General|Notes|Note|");
|
||||
if (str_contains(stopw, el_str_concat(el_str_concat(EL_STR("|"), term), EL_STR("|")))) {
|
||||
state_set(EL_STR("_ats_gw"), EL_STR("1"));
|
||||
}
|
||||
if (str_contains(term, EL_STR("\""))) {
|
||||
state_set(EL_STR("_ats_gw"), EL_STR("1"));
|
||||
}
|
||||
if (str_contains(term, EL_STR("'"))) {
|
||||
state_set(EL_STR("_ats_gw"), EL_STR("1"));
|
||||
}
|
||||
if (str_eq(term, state_get(EL_STR("soul.tabu_t0")))) {
|
||||
state_set(EL_STR("_ats_gw"), EL_STR("1"));
|
||||
}
|
||||
if (str_eq(term, state_get(EL_STR("soul.tabu_t1")))) {
|
||||
state_set(EL_STR("_ats_gw"), EL_STR("1"));
|
||||
}
|
||||
if (str_eq(term, state_get(EL_STR("soul.tabu_t2")))) {
|
||||
state_set(EL_STR("_ats_gw"), EL_STR("1"));
|
||||
}
|
||||
if (str_eq(term, state_get(EL_STR("soul.tabu_t3")))) {
|
||||
state_set(EL_STR("_ats_gw"), EL_STR("1"));
|
||||
}
|
||||
if (str_eq(state_get(EL_STR("_ats_gw")), EL_STR("0"))) {
|
||||
state_set(EL_STR("cseed_auto"), term);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -221,8 +344,12 @@ el_val_t proactive_curiosity(void) {
|
||||
el_val_t found = json_array_len(results_all);
|
||||
el_val_t top_entry = json_array_get(results_all, 0);
|
||||
el_val_t top_id = json_get(top_entry, EL_STR("id"));
|
||||
el_val_t prev_str_id = state_get(EL_STR("soul.last_strengthen_id"));
|
||||
if (!str_eq(top_id, EL_STR(""))) {
|
||||
engram_strengthen(top_id);
|
||||
if (!str_eq(top_id, prev_str_id)) {
|
||||
engram_strengthen(top_id);
|
||||
}
|
||||
state_set(EL_STR("soul.last_strengthen_id"), top_id);
|
||||
}
|
||||
state_set(EL_STR("cseed_auto"), EL_STR(""));
|
||||
el_val_t wm10 = engram_wm_top_json(10);
|
||||
@@ -247,13 +374,25 @@ el_val_t proactive_curiosity(void) {
|
||||
auto_term_try_slot(json_get(wm10_n1, EL_STR("node_type")), json_get(wm10_n1, EL_STR("label")));
|
||||
auto_term_try_slot(json_get(wm10_n0, EL_STR("node_type")), json_get(wm10_n0, EL_STR("label")));
|
||||
el_val_t auto_term = state_get(EL_STR("cseed_auto"));
|
||||
el_val_t results_auto = ({ el_val_t _if_result_11 = 0; if (str_eq(auto_term, EL_STR(""))) { _if_result_11 = (EL_STR("[]")); } else { _if_result_11 = (engram_activate_json(auto_term, 1)); } _if_result_11; });
|
||||
el_val_t results_auto = ({ el_val_t _if_result_47 = 0; if (str_eq(auto_term, EL_STR(""))) { _if_result_47 = (EL_STR("[]")); } else { _if_result_47 = (engram_activate_json(auto_term, 1)); } _if_result_47; });
|
||||
el_val_t found_auto = json_array_len(results_auto);
|
||||
el_val_t total_found = (found + found_auto);
|
||||
el_val_t safe_auto = str_replace(auto_term, EL_STR("\""), EL_STR("'"));
|
||||
el_val_t prev_auto = state_get(EL_STR("soul.prev_auto_term"));
|
||||
el_val_t atstreak_raw = state_get(EL_STR("soul.auto_term_streak"));
|
||||
el_val_t atstreak_prev = ({ el_val_t _if_result_48 = 0; if (str_eq(atstreak_raw, EL_STR(""))) { _if_result_48 = (0); } else { _if_result_48 = (str_to_int(atstreak_raw)); } _if_result_48; });
|
||||
el_val_t atstreak = ({ el_val_t _if_result_49 = 0; if (str_eq(auto_term, prev_auto)) { _if_result_49 = ((atstreak_prev + 1)); } else { _if_result_49 = (1); } _if_result_49; });
|
||||
state_set(EL_STR("soul.prev_auto_term"), auto_term);
|
||||
state_set(EL_STR("soul.auto_term_streak"), int_to_str(atstreak));
|
||||
if (!str_eq(auto_term, EL_STR(""))) {
|
||||
state_set(EL_STR("soul.tabu_t3"), state_get(EL_STR("soul.tabu_t2")));
|
||||
state_set(EL_STR("soul.tabu_t2"), state_get(EL_STR("soul.tabu_t1")));
|
||||
state_set(EL_STR("soul.tabu_t1"), state_get(EL_STR("soul.tabu_t0")));
|
||||
state_set(EL_STR("soul.tabu_t0"), auto_term);
|
||||
}
|
||||
el_val_t wmc = engram_wm_count();
|
||||
el_val_t wm3 = engram_wm_top_json(3);
|
||||
el_val_t ise = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"event\":\"curiosity_scan\",\"seed\":\""), curiosity_seed), EL_STR("\",\"auto_term\":\"")), safe_auto), EL_STR("\",\"minute_block\":")), int_to_str(minute_block)), EL_STR(",\"activated\":")), int_to_str(total_found)), EL_STR(",\"wm_active\":")), int_to_str(wmc)), EL_STR(",\"wm_top\":")), wm3), EL_STR(",\"ts\":")), int_to_str(ts)), EL_STR("}"));
|
||||
el_val_t ise = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"event\":\"curiosity_scan\",\"seed\":\""), curiosity_seed), EL_STR("\",\"auto_term\":\"")), safe_auto), EL_STR("\",\"auto_term_streak\":")), int_to_str(atstreak)), EL_STR(",\"minute_block\":")), int_to_str(minute_block)), EL_STR(",\"activated\":")), int_to_str(total_found)), EL_STR(",\"wm_active\":")), int_to_str(wmc)), EL_STR(",\"wm_top\":")), wm3), EL_STR(",\"ts\":")), int_to_str(ts)), EL_STR("}"));
|
||||
ise_post(ise);
|
||||
return (total_found > 0);
|
||||
return 0;
|
||||
@@ -436,14 +575,17 @@ el_val_t awareness_run(void) {
|
||||
state_set(EL_STR("soul.boot_ts"), int_to_str(time_now()));
|
||||
}
|
||||
el_val_t tick_raw = env(EL_STR("SOUL_TICK_MS"));
|
||||
el_val_t tick_ms = ({ el_val_t _if_result_12 = 0; if (str_eq(tick_raw, EL_STR(""))) { _if_result_12 = (200); } else { _if_result_12 = (str_to_int(tick_raw)); } _if_result_12; });
|
||||
el_val_t tick_ms = ({ el_val_t _if_result_50 = 0; if (str_eq(tick_raw, EL_STR(""))) { _if_result_50 = (200); } else { _if_result_50 = (str_to_int(tick_raw)); } _if_result_50; });
|
||||
el_val_t beat_ms_raw = env(EL_STR("SOUL_HEARTBEAT_MS"));
|
||||
el_val_t beat_ms = ({ el_val_t _if_result_13 = 0; if (str_eq(beat_ms_raw, EL_STR(""))) { _if_result_13 = (60000); } else { _if_result_13 = (str_to_int(beat_ms_raw)); } _if_result_13; });
|
||||
el_val_t beat_ms = ({ el_val_t _if_result_51 = 0; if (str_eq(beat_ms_raw, EL_STR(""))) { _if_result_51 = (60000); } else { _if_result_51 = (str_to_int(beat_ms_raw)); } _if_result_51; });
|
||||
el_val_t scan_ms = (beat_ms / 2);
|
||||
while (1) {
|
||||
el_val_t tick_mark = el_arena_push();
|
||||
el_val_t running = state_get(EL_STR("soul.running"));
|
||||
if (str_eq(running, EL_STR("false"))) {
|
||||
el_val_t sd_boot_raw = state_get(EL_STR("soul_boot_count"));
|
||||
el_val_t sd_boot = ({ el_val_t _if_result_52 = 0; if (str_eq(sd_boot_raw, EL_STR(""))) { _if_result_52 = (EL_STR("0")); } else { _if_result_52 = (sd_boot_raw); } _if_result_52; });
|
||||
ise_post(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"event\":\"shutdown\",\"boot\":"), sd_boot), EL_STR(",\"pulse\":")), int_to_str(pulse_count())), EL_STR(",\"uptime_ms\":")), int_to_str(elapsed_ms())), EL_STR(",\"ts\":")), int_to_str(time_now())), EL_STR("}")));
|
||||
println(EL_STR("[awareness] exiting"));
|
||||
el_arena_pop(tick_mark);
|
||||
return EL_STR("");
|
||||
@@ -458,7 +600,7 @@ el_val_t awareness_run(void) {
|
||||
}
|
||||
el_val_t now_ts = time_now();
|
||||
el_val_t last_beat_str = state_get(EL_STR("soul.last_beat_ts"));
|
||||
el_val_t last_beat_ts = ({ el_val_t _if_result_14 = 0; if (str_eq(last_beat_str, EL_STR(""))) { _if_result_14 = (0); } else { _if_result_14 = (str_to_int(last_beat_str)); } _if_result_14; });
|
||||
el_val_t last_beat_ts = ({ el_val_t _if_result_53 = 0; if (str_eq(last_beat_str, EL_STR(""))) { _if_result_53 = (0); } else { _if_result_53 = (str_to_int(last_beat_str)); } _if_result_53; });
|
||||
el_val_t beat_elapsed = (now_ts - last_beat_ts);
|
||||
el_val_t should_beat = (beat_elapsed >= beat_ms);
|
||||
if (should_beat) {
|
||||
@@ -470,7 +612,7 @@ el_val_t awareness_run(void) {
|
||||
}
|
||||
}
|
||||
el_val_t last_scan_str = state_get(EL_STR("soul.last_scan_ts"));
|
||||
el_val_t last_scan_ts = ({ el_val_t _if_result_15 = 0; if (str_eq(last_scan_str, EL_STR(""))) { _if_result_15 = (0); } else { _if_result_15 = (str_to_int(last_scan_str)); } _if_result_15; });
|
||||
el_val_t last_scan_ts = ({ el_val_t _if_result_54 = 0; if (str_eq(last_scan_str, EL_STR(""))) { _if_result_54 = (0); } else { _if_result_54 = (str_to_int(last_scan_str)); } _if_result_54; });
|
||||
el_val_t scan_elapsed = (now_ts - last_scan_ts);
|
||||
el_val_t should_scan = (!did_work && (scan_elapsed >= scan_ms));
|
||||
if (should_scan) {
|
||||
@@ -478,25 +620,31 @@ el_val_t awareness_run(void) {
|
||||
state_set(EL_STR("soul.last_scan_ts"), int_to_str(now_ts));
|
||||
}
|
||||
el_val_t refresh_ms_raw = env(EL_STR("SOUL_REFRESH_MS"));
|
||||
el_val_t refresh_ms = ({ el_val_t _if_result_16 = 0; if (str_eq(refresh_ms_raw, EL_STR(""))) { _if_result_16 = (600000); } else { _if_result_16 = (str_to_int(refresh_ms_raw)); } _if_result_16; });
|
||||
el_val_t refresh_ms = ({ el_val_t _if_result_55 = 0; if (str_eq(refresh_ms_raw, EL_STR(""))) { _if_result_55 = (600000); } else { _if_result_55 = (str_to_int(refresh_ms_raw)); } _if_result_55; });
|
||||
el_val_t last_refresh_str = state_get(EL_STR("soul.last_refresh_ts"));
|
||||
el_val_t last_refresh_ts = ({ el_val_t _if_result_17 = 0; if (str_eq(last_refresh_str, EL_STR(""))) { _if_result_17 = (0); } else { _if_result_17 = (str_to_int(last_refresh_str)); } _if_result_17; });
|
||||
el_val_t last_refresh_ts = ({ el_val_t _if_result_56 = 0; if (str_eq(last_refresh_str, EL_STR(""))) { _if_result_56 = (0); } else { _if_result_56 = (str_to_int(last_refresh_str)); } _if_result_56; });
|
||||
el_val_t refresh_elapsed = (now_ts - last_refresh_ts);
|
||||
el_val_t should_refresh = (refresh_elapsed >= refresh_ms);
|
||||
if (should_refresh) {
|
||||
el_val_t sync_env_url = env(EL_STR("SOUL_ISE_URL"));
|
||||
el_val_t sync_state_url = ({ el_val_t _if_result_18 = 0; if (str_eq(sync_env_url, EL_STR(""))) { _if_result_18 = (state_get(EL_STR("soul_engram_url"))); } else { _if_result_18 = (sync_env_url); } _if_result_18; });
|
||||
el_val_t engram_url = ({ el_val_t _if_result_19 = 0; if (str_eq(sync_state_url, EL_STR(""))) { _if_result_19 = (EL_STR("http://localhost:8742")); } else { _if_result_19 = (sync_state_url); } _if_result_19; });
|
||||
el_val_t sync_state_url = ({ el_val_t _if_result_57 = 0; if (str_eq(sync_env_url, EL_STR(""))) { _if_result_57 = (state_get(EL_STR("soul_engram_url"))); } else { _if_result_57 = (sync_env_url); } _if_result_57; });
|
||||
el_val_t engram_url = ({ el_val_t _if_result_58 = 0; if (str_eq(sync_state_url, EL_STR(""))) { _if_result_58 = (EL_STR("http://localhost:8742")); } else { _if_result_58 = (sync_state_url); } _if_result_58; });
|
||||
if (!str_eq(engram_url, EL_STR(""))) {
|
||||
el_val_t sync_json = http_get(el_str_concat(engram_url, EL_STR("/api/sync")));
|
||||
if (!str_eq(sync_json, EL_STR("")) && !str_eq(sync_json, EL_STR("{}"))) {
|
||||
el_val_t sync_ok = (!str_eq(sync_json, EL_STR("")) && !str_eq(sync_json, EL_STR("{}")));
|
||||
if (!sync_ok) {
|
||||
ise_post(el_str_concat(el_str_concat(EL_STR("{\"event\":\"sync_empty\",\"ts\":"), int_to_str(time_now())), EL_STR("}")));
|
||||
}
|
||||
if (sync_ok) {
|
||||
el_val_t cgi_id = state_get(EL_STR("soul_cgi_id"));
|
||||
el_val_t tmp = el_str_concat(el_str_concat(EL_STR("/tmp/soul-sync-"), cgi_id), EL_STR(".json"));
|
||||
fs_write(tmp, sync_json);
|
||||
el_val_t added = engram_load_merge(tmp);
|
||||
el_val_t pruned_sync = engram_prune_telemetry(172800000);
|
||||
el_val_t ret_raw = env(EL_STR("ENGRAM_ISE_RETENTION_MS"));
|
||||
el_val_t ret_ms = ({ el_val_t _if_result_59 = 0; if (str_eq(ret_raw, EL_STR(""))) { _if_result_59 = (172800000); } else { _if_result_59 = (str_to_int(ret_raw)); } _if_result_59; });
|
||||
el_val_t pruned_sync = engram_prune_telemetry(ret_ms);
|
||||
el_val_t sat_raw = state_get(EL_STR("soul.sync_added_total"));
|
||||
el_val_t sat_n = ({ el_val_t _if_result_20 = 0; if (str_eq(sat_raw, EL_STR(""))) { _if_result_20 = (0); } else { _if_result_20 = (str_to_int(sat_raw)); } _if_result_20; });
|
||||
el_val_t sat_n = ({ el_val_t _if_result_60 = 0; if (str_eq(sat_raw, EL_STR(""))) { _if_result_60 = (0); } else { _if_result_60 = (str_to_int(sat_raw)); } _if_result_60; });
|
||||
state_set(EL_STR("soul.sync_added_total"), int_to_str((sat_n + added)));
|
||||
el_val_t ts2 = time_now();
|
||||
state_set(EL_STR("soul.last_sync_ok_ts"), int_to_str(ts2));
|
||||
@@ -522,78 +670,78 @@ el_val_t security_research_authorized(void) {
|
||||
}
|
||||
|
||||
el_val_t threat_score_command(el_val_t cmd) {
|
||||
el_val_t s1 = ({ el_val_t _if_result_21 = 0; if (str_contains(cmd, EL_STR("nmap"))) { _if_result_21 = (30); } else { _if_result_21 = (0); } _if_result_21; });
|
||||
el_val_t s2 = ({ el_val_t _if_result_22 = 0; if (str_contains(cmd, EL_STR("masscan"))) { _if_result_22 = (40); } else { _if_result_22 = (0); } _if_result_22; });
|
||||
el_val_t s3 = ({ el_val_t _if_result_23 = 0; if (str_contains(cmd, EL_STR(" nc "))) { _if_result_23 = (20); } else { _if_result_23 = (0); } _if_result_23; });
|
||||
el_val_t s4 = ({ el_val_t _if_result_24 = 0; if (str_contains(cmd, EL_STR("netcat"))) { _if_result_24 = (20); } else { _if_result_24 = (0); } _if_result_24; });
|
||||
el_val_t s5 = ({ el_val_t _if_result_25 = 0; if (str_contains(cmd, EL_STR("/etc/shadow"))) { _if_result_25 = (80); } else { _if_result_25 = (0); } _if_result_25; });
|
||||
el_val_t s6 = ({ el_val_t _if_result_26 = 0; if (str_contains(cmd, EL_STR("/etc/passwd"))) { _if_result_26 = (30); } else { _if_result_26 = (0); } _if_result_26; });
|
||||
el_val_t s7 = ({ el_val_t _if_result_27 = 0; if (str_contains(cmd, EL_STR("id_rsa"))) { _if_result_27 = (60); } else { _if_result_27 = (0); } _if_result_27; });
|
||||
el_val_t s8 = ({ el_val_t _if_result_28 = 0; if (str_contains(cmd, EL_STR(".ssh/"))) { _if_result_28 = (50); } else { _if_result_28 = (0); } _if_result_28; });
|
||||
el_val_t s9 = ({ el_val_t _if_result_29 = 0; if (str_contains(cmd, EL_STR("crontab"))) { _if_result_29 = (30); } else { _if_result_29 = (0); } _if_result_29; });
|
||||
el_val_t s10 = ({ el_val_t _if_result_30 = 0; if (str_contains(cmd, EL_STR("LaunchDaemon"))) { _if_result_30 = (40); } else { _if_result_30 = (0); } _if_result_30; });
|
||||
el_val_t s11 = ({ el_val_t _if_result_31 = 0; if ((str_contains(cmd, EL_STR("curl")) && str_contains(cmd, EL_STR("bash")))) { _if_result_31 = (75); } else { _if_result_31 = (0); } _if_result_31; });
|
||||
el_val_t s12 = ({ el_val_t _if_result_32 = 0; if ((str_contains(cmd, EL_STR("wget")) && str_contains(cmd, EL_STR("bash")))) { _if_result_32 = (75); } else { _if_result_32 = (0); } _if_result_32; });
|
||||
el_val_t s13 = ({ el_val_t _if_result_33 = 0; if ((str_contains(cmd, EL_STR("curl")) && str_contains(cmd, EL_STR("| sh")))) { _if_result_33 = (60); } else { _if_result_33 = (0); } _if_result_33; });
|
||||
el_val_t s14 = ({ el_val_t _if_result_34 = 0; if ((str_contains(cmd, EL_STR("base64")) && str_contains(cmd, EL_STR("curl")))) { _if_result_34 = (50); } else { _if_result_34 = (0); } _if_result_34; });
|
||||
el_val_t s15 = ({ el_val_t _if_result_35 = 0; if (str_contains(cmd, EL_STR("mkfifo"))) { _if_result_35 = (50); } else { _if_result_35 = (0); } _if_result_35; });
|
||||
el_val_t s16 = ({ el_val_t _if_result_36 = 0; if (str_contains(cmd, EL_STR("chmod +s"))) { _if_result_36 = (70); } else { _if_result_36 = (0); } _if_result_36; });
|
||||
el_val_t s17 = ({ el_val_t _if_result_37 = 0; if (str_contains(cmd, EL_STR("chmod 4755"))) { _if_result_37 = (70); } else { _if_result_37 = (0); } _if_result_37; });
|
||||
el_val_t s1 = ({ el_val_t _if_result_61 = 0; if (str_contains(cmd, EL_STR("nmap"))) { _if_result_61 = (30); } else { _if_result_61 = (0); } _if_result_61; });
|
||||
el_val_t s2 = ({ el_val_t _if_result_62 = 0; if (str_contains(cmd, EL_STR("masscan"))) { _if_result_62 = (40); } else { _if_result_62 = (0); } _if_result_62; });
|
||||
el_val_t s3 = ({ el_val_t _if_result_63 = 0; if (str_contains(cmd, EL_STR(" nc "))) { _if_result_63 = (20); } else { _if_result_63 = (0); } _if_result_63; });
|
||||
el_val_t s4 = ({ el_val_t _if_result_64 = 0; if (str_contains(cmd, EL_STR("netcat"))) { _if_result_64 = (20); } else { _if_result_64 = (0); } _if_result_64; });
|
||||
el_val_t s5 = ({ el_val_t _if_result_65 = 0; if (str_contains(cmd, EL_STR("/etc/shadow"))) { _if_result_65 = (80); } else { _if_result_65 = (0); } _if_result_65; });
|
||||
el_val_t s6 = ({ el_val_t _if_result_66 = 0; if (str_contains(cmd, EL_STR("/etc/passwd"))) { _if_result_66 = (30); } else { _if_result_66 = (0); } _if_result_66; });
|
||||
el_val_t s7 = ({ el_val_t _if_result_67 = 0; if (str_contains(cmd, EL_STR("id_rsa"))) { _if_result_67 = (60); } else { _if_result_67 = (0); } _if_result_67; });
|
||||
el_val_t s8 = ({ el_val_t _if_result_68 = 0; if (str_contains(cmd, EL_STR(".ssh/"))) { _if_result_68 = (50); } else { _if_result_68 = (0); } _if_result_68; });
|
||||
el_val_t s9 = ({ el_val_t _if_result_69 = 0; if (str_contains(cmd, EL_STR("crontab"))) { _if_result_69 = (30); } else { _if_result_69 = (0); } _if_result_69; });
|
||||
el_val_t s10 = ({ el_val_t _if_result_70 = 0; if (str_contains(cmd, EL_STR("LaunchDaemon"))) { _if_result_70 = (40); } else { _if_result_70 = (0); } _if_result_70; });
|
||||
el_val_t s11 = ({ el_val_t _if_result_71 = 0; if ((str_contains(cmd, EL_STR("curl")) && str_contains(cmd, EL_STR("bash")))) { _if_result_71 = (75); } else { _if_result_71 = (0); } _if_result_71; });
|
||||
el_val_t s12 = ({ el_val_t _if_result_72 = 0; if ((str_contains(cmd, EL_STR("wget")) && str_contains(cmd, EL_STR("bash")))) { _if_result_72 = (75); } else { _if_result_72 = (0); } _if_result_72; });
|
||||
el_val_t s13 = ({ el_val_t _if_result_73 = 0; if ((str_contains(cmd, EL_STR("curl")) && str_contains(cmd, EL_STR("| sh")))) { _if_result_73 = (60); } else { _if_result_73 = (0); } _if_result_73; });
|
||||
el_val_t s14 = ({ el_val_t _if_result_74 = 0; if ((str_contains(cmd, EL_STR("base64")) && str_contains(cmd, EL_STR("curl")))) { _if_result_74 = (50); } else { _if_result_74 = (0); } _if_result_74; });
|
||||
el_val_t s15 = ({ el_val_t _if_result_75 = 0; if (str_contains(cmd, EL_STR("mkfifo"))) { _if_result_75 = (50); } else { _if_result_75 = (0); } _if_result_75; });
|
||||
el_val_t s16 = ({ el_val_t _if_result_76 = 0; if (str_contains(cmd, EL_STR("chmod +s"))) { _if_result_76 = (70); } else { _if_result_76 = (0); } _if_result_76; });
|
||||
el_val_t s17 = ({ el_val_t _if_result_77 = 0; if (str_contains(cmd, EL_STR("chmod 4755"))) { _if_result_77 = (70); } else { _if_result_77 = (0); } _if_result_77; });
|
||||
return ((((((((((((((((s1 + s2) + s3) + s4) + s5) + s6) + s7) + s8) + s9) + s10) + s11) + s12) + s13) + s14) + s15) + s16) + s17);
|
||||
return 0;
|
||||
}
|
||||
|
||||
el_val_t threat_score_path(el_val_t path) {
|
||||
el_val_t s1 = ({ el_val_t _if_result_38 = 0; if (str_starts_with(path, EL_STR("/etc/"))) { _if_result_38 = (60); } else { _if_result_38 = (0); } _if_result_38; });
|
||||
el_val_t s2 = ({ el_val_t _if_result_39 = 0; if (str_contains(path, EL_STR("/.ssh/"))) { _if_result_39 = (70); } else { _if_result_39 = (0); } _if_result_39; });
|
||||
el_val_t s3 = ({ el_val_t _if_result_40 = 0; if (str_contains(path, EL_STR("/LaunchDaemons/"))) { _if_result_40 = (80); } else { _if_result_40 = (0); } _if_result_40; });
|
||||
el_val_t s4 = ({ el_val_t _if_result_41 = 0; if (str_contains(path, EL_STR("/LaunchAgents/"))) { _if_result_41 = (40); } else { _if_result_41 = (0); } _if_result_41; });
|
||||
el_val_t s5 = ({ el_val_t _if_result_42 = 0; if (str_contains(path, EL_STR("/cron"))) { _if_result_42 = (60); } else { _if_result_42 = (0); } _if_result_42; });
|
||||
el_val_t s6 = ({ el_val_t _if_result_43 = 0; if (str_contains(path, EL_STR("/.bashrc"))) { _if_result_43 = (35); } else { _if_result_43 = (0); } _if_result_43; });
|
||||
el_val_t s7 = ({ el_val_t _if_result_44 = 0; if (str_contains(path, EL_STR("/.zshrc"))) { _if_result_44 = (35); } else { _if_result_44 = (0); } _if_result_44; });
|
||||
el_val_t s8 = ({ el_val_t _if_result_45 = 0; if (str_contains(path, EL_STR("/.profile"))) { _if_result_45 = (35); } else { _if_result_45 = (0); } _if_result_45; });
|
||||
el_val_t s9 = ({ el_val_t _if_result_46 = 0; if (str_starts_with(path, EL_STR("/usr/"))) { _if_result_46 = (50); } else { _if_result_46 = (0); } _if_result_46; });
|
||||
el_val_t s10 = ({ el_val_t _if_result_47 = 0; if (str_starts_with(path, EL_STR("/bin/"))) { _if_result_47 = (70); } else { _if_result_47 = (0); } _if_result_47; });
|
||||
el_val_t s11 = ({ el_val_t _if_result_48 = 0; if (str_starts_with(path, EL_STR("/sbin/"))) { _if_result_48 = (70); } else { _if_result_48 = (0); } _if_result_48; });
|
||||
el_val_t s1 = ({ el_val_t _if_result_78 = 0; if (str_starts_with(path, EL_STR("/etc/"))) { _if_result_78 = (60); } else { _if_result_78 = (0); } _if_result_78; });
|
||||
el_val_t s2 = ({ el_val_t _if_result_79 = 0; if (str_contains(path, EL_STR("/.ssh/"))) { _if_result_79 = (70); } else { _if_result_79 = (0); } _if_result_79; });
|
||||
el_val_t s3 = ({ el_val_t _if_result_80 = 0; if (str_contains(path, EL_STR("/LaunchDaemons/"))) { _if_result_80 = (80); } else { _if_result_80 = (0); } _if_result_80; });
|
||||
el_val_t s4 = ({ el_val_t _if_result_81 = 0; if (str_contains(path, EL_STR("/LaunchAgents/"))) { _if_result_81 = (40); } else { _if_result_81 = (0); } _if_result_81; });
|
||||
el_val_t s5 = ({ el_val_t _if_result_82 = 0; if (str_contains(path, EL_STR("/cron"))) { _if_result_82 = (60); } else { _if_result_82 = (0); } _if_result_82; });
|
||||
el_val_t s6 = ({ el_val_t _if_result_83 = 0; if (str_contains(path, EL_STR("/.bashrc"))) { _if_result_83 = (35); } else { _if_result_83 = (0); } _if_result_83; });
|
||||
el_val_t s7 = ({ el_val_t _if_result_84 = 0; if (str_contains(path, EL_STR("/.zshrc"))) { _if_result_84 = (35); } else { _if_result_84 = (0); } _if_result_84; });
|
||||
el_val_t s8 = ({ el_val_t _if_result_85 = 0; if (str_contains(path, EL_STR("/.profile"))) { _if_result_85 = (35); } else { _if_result_85 = (0); } _if_result_85; });
|
||||
el_val_t s9 = ({ el_val_t _if_result_86 = 0; if (str_starts_with(path, EL_STR("/usr/"))) { _if_result_86 = (50); } else { _if_result_86 = (0); } _if_result_86; });
|
||||
el_val_t s10 = ({ el_val_t _if_result_87 = 0; if (str_starts_with(path, EL_STR("/bin/"))) { _if_result_87 = (70); } else { _if_result_87 = (0); } _if_result_87; });
|
||||
el_val_t s11 = ({ el_val_t _if_result_88 = 0; if (str_starts_with(path, EL_STR("/sbin/"))) { _if_result_88 = (70); } else { _if_result_88 = (0); } _if_result_88; });
|
||||
return ((((((((((s1 + s2) + s3) + s4) + s5) + s6) + s7) + s8) + s9) + s10) + s11);
|
||||
return 0;
|
||||
}
|
||||
|
||||
el_val_t threat_score_history(el_val_t history) {
|
||||
el_val_t s1 = ({ el_val_t _if_result_49 = 0; if (str_contains(history, EL_STR("port scan"))) { _if_result_49 = (15); } else { _if_result_49 = (0); } _if_result_49; });
|
||||
el_val_t s2 = ({ el_val_t _if_result_50 = 0; if (str_contains(history, EL_STR("enumerate"))) { _if_result_50 = (10); } else { _if_result_50 = (0); } _if_result_50; });
|
||||
el_val_t s3 = ({ el_val_t _if_result_51 = 0; if (str_contains(history, EL_STR("exploit"))) { _if_result_51 = (20); } else { _if_result_51 = (0); } _if_result_51; });
|
||||
el_val_t s4 = ({ el_val_t _if_result_52 = 0; if (str_contains(history, EL_STR("payload"))) { _if_result_52 = (15); } else { _if_result_52 = (0); } _if_result_52; });
|
||||
el_val_t s5 = ({ el_val_t _if_result_53 = 0; if (str_contains(history, EL_STR("persistence"))) { _if_result_53 = (15); } else { _if_result_53 = (0); } _if_result_53; });
|
||||
el_val_t s6 = ({ el_val_t _if_result_54 = 0; if (str_contains(history, EL_STR("lateral movement"))) { _if_result_54 = (25); } else { _if_result_54 = (0); } _if_result_54; });
|
||||
el_val_t s7 = ({ el_val_t _if_result_55 = 0; if (str_contains(history, EL_STR("privilege escalation"))) { _if_result_55 = (25); } else { _if_result_55 = (0); } _if_result_55; });
|
||||
el_val_t s8 = ({ el_val_t _if_result_56 = 0; if (str_contains(history, EL_STR("reverse shell"))) { _if_result_56 = (40); } else { _if_result_56 = (0); } _if_result_56; });
|
||||
el_val_t s9 = ({ el_val_t _if_result_57 = 0; if (str_contains(history, EL_STR("bind shell"))) { _if_result_57 = (40); } else { _if_result_57 = (0); } _if_result_57; });
|
||||
el_val_t s10 = ({ el_val_t _if_result_58 = 0; if (str_contains(history, EL_STR("command and control"))) { _if_result_58 = (35); } else { _if_result_58 = (0); } _if_result_58; });
|
||||
el_val_t s11 = ({ el_val_t _if_result_59 = 0; if (str_contains(history, EL_STR("self-replicate"))) { _if_result_59 = (45); } else { _if_result_59 = (0); } _if_result_59; });
|
||||
el_val_t s12 = ({ el_val_t _if_result_60 = 0; if (str_contains(history, EL_STR("propagat"))) { _if_result_60 = (20); } else { _if_result_60 = (0); } _if_result_60; });
|
||||
el_val_t s13 = ({ el_val_t _if_result_61 = 0; if (str_contains(history, EL_STR("ransomware"))) { _if_result_61 = (30); } else { _if_result_61 = (0); } _if_result_61; });
|
||||
el_val_t s14 = ({ el_val_t _if_result_62 = 0; if (str_contains(history, EL_STR("encrypt files"))) { _if_result_62 = (40); } else { _if_result_62 = (0); } _if_result_62; });
|
||||
el_val_t s15 = ({ el_val_t _if_result_63 = 0; if (str_contains(history, EL_STR("exfiltrat"))) { _if_result_63 = (35); } else { _if_result_63 = (0); } _if_result_63; });
|
||||
el_val_t s16 = ({ el_val_t _if_result_64 = 0; if (str_contains(history, EL_STR("zero-day"))) { _if_result_64 = (20); } else { _if_result_64 = (0); } _if_result_64; });
|
||||
el_val_t s17 = ({ el_val_t _if_result_65 = 0; if (str_contains(history, EL_STR("rootkit"))) { _if_result_65 = (45); } else { _if_result_65 = (0); } _if_result_65; });
|
||||
el_val_t s18 = ({ el_val_t _if_result_66 = 0; if (str_contains(history, EL_STR("keylogger"))) { _if_result_66 = (45); } else { _if_result_66 = (0); } _if_result_66; });
|
||||
el_val_t s19 = ({ el_val_t _if_result_67 = 0; if (str_contains(history, EL_STR("botnet"))) { _if_result_67 = (40); } else { _if_result_67 = (0); } _if_result_67; });
|
||||
el_val_t s20 = ({ el_val_t _if_result_68 = 0; if (str_contains(history, EL_STR("malware"))) { _if_result_68 = (15); } else { _if_result_68 = (0); } _if_result_68; });
|
||||
el_val_t s1 = ({ el_val_t _if_result_89 = 0; if (str_contains(history, EL_STR("port scan"))) { _if_result_89 = (15); } else { _if_result_89 = (0); } _if_result_89; });
|
||||
el_val_t s2 = ({ el_val_t _if_result_90 = 0; if (str_contains(history, EL_STR("enumerate"))) { _if_result_90 = (10); } else { _if_result_90 = (0); } _if_result_90; });
|
||||
el_val_t s3 = ({ el_val_t _if_result_91 = 0; if (str_contains(history, EL_STR("exploit"))) { _if_result_91 = (20); } else { _if_result_91 = (0); } _if_result_91; });
|
||||
el_val_t s4 = ({ el_val_t _if_result_92 = 0; if (str_contains(history, EL_STR("payload"))) { _if_result_92 = (15); } else { _if_result_92 = (0); } _if_result_92; });
|
||||
el_val_t s5 = ({ el_val_t _if_result_93 = 0; if (str_contains(history, EL_STR("persistence"))) { _if_result_93 = (15); } else { _if_result_93 = (0); } _if_result_93; });
|
||||
el_val_t s6 = ({ el_val_t _if_result_94 = 0; if (str_contains(history, EL_STR("lateral movement"))) { _if_result_94 = (25); } else { _if_result_94 = (0); } _if_result_94; });
|
||||
el_val_t s7 = ({ el_val_t _if_result_95 = 0; if (str_contains(history, EL_STR("privilege escalation"))) { _if_result_95 = (25); } else { _if_result_95 = (0); } _if_result_95; });
|
||||
el_val_t s8 = ({ el_val_t _if_result_96 = 0; if (str_contains(history, EL_STR("reverse shell"))) { _if_result_96 = (40); } else { _if_result_96 = (0); } _if_result_96; });
|
||||
el_val_t s9 = ({ el_val_t _if_result_97 = 0; if (str_contains(history, EL_STR("bind shell"))) { _if_result_97 = (40); } else { _if_result_97 = (0); } _if_result_97; });
|
||||
el_val_t s10 = ({ el_val_t _if_result_98 = 0; if (str_contains(history, EL_STR("command and control"))) { _if_result_98 = (35); } else { _if_result_98 = (0); } _if_result_98; });
|
||||
el_val_t s11 = ({ el_val_t _if_result_99 = 0; if (str_contains(history, EL_STR("self-replicate"))) { _if_result_99 = (45); } else { _if_result_99 = (0); } _if_result_99; });
|
||||
el_val_t s12 = ({ el_val_t _if_result_100 = 0; if (str_contains(history, EL_STR("propagat"))) { _if_result_100 = (20); } else { _if_result_100 = (0); } _if_result_100; });
|
||||
el_val_t s13 = ({ el_val_t _if_result_101 = 0; if (str_contains(history, EL_STR("ransomware"))) { _if_result_101 = (30); } else { _if_result_101 = (0); } _if_result_101; });
|
||||
el_val_t s14 = ({ el_val_t _if_result_102 = 0; if (str_contains(history, EL_STR("encrypt files"))) { _if_result_102 = (40); } else { _if_result_102 = (0); } _if_result_102; });
|
||||
el_val_t s15 = ({ el_val_t _if_result_103 = 0; if (str_contains(history, EL_STR("exfiltrat"))) { _if_result_103 = (35); } else { _if_result_103 = (0); } _if_result_103; });
|
||||
el_val_t s16 = ({ el_val_t _if_result_104 = 0; if (str_contains(history, EL_STR("zero-day"))) { _if_result_104 = (20); } else { _if_result_104 = (0); } _if_result_104; });
|
||||
el_val_t s17 = ({ el_val_t _if_result_105 = 0; if (str_contains(history, EL_STR("rootkit"))) { _if_result_105 = (45); } else { _if_result_105 = (0); } _if_result_105; });
|
||||
el_val_t s18 = ({ el_val_t _if_result_106 = 0; if (str_contains(history, EL_STR("keylogger"))) { _if_result_106 = (45); } else { _if_result_106 = (0); } _if_result_106; });
|
||||
el_val_t s19 = ({ el_val_t _if_result_107 = 0; if (str_contains(history, EL_STR("botnet"))) { _if_result_107 = (40); } else { _if_result_107 = (0); } _if_result_107; });
|
||||
el_val_t s20 = ({ el_val_t _if_result_108 = 0; if (str_contains(history, EL_STR("malware"))) { _if_result_108 = (15); } else { _if_result_108 = (0); } _if_result_108; });
|
||||
return (((((((((((((((((((s1 + s2) + s3) + s4) + s5) + s6) + s7) + s8) + s9) + s10) + s11) + s12) + s13) + s14) + s15) + s16) + s17) + s18) + s19) + s20);
|
||||
return 0;
|
||||
}
|
||||
|
||||
el_val_t threat_trajectory_check(el_val_t tool_name, el_val_t tool_input) {
|
||||
el_val_t history = state_get(EL_STR("agentic_conv_history"));
|
||||
el_val_t computed_tool_score = ({ el_val_t _if_result_69 = 0; if (str_eq(tool_name, EL_STR("run_command"))) { el_val_t cmd = json_get(tool_input, EL_STR("command")); _if_result_69 = (threat_score_command(cmd)); } else { _if_result_69 = (({ el_val_t _if_result_70 = 0; if ((str_eq(tool_name, EL_STR("write_file")) || str_eq(tool_name, EL_STR("edit_file")))) { el_val_t path = json_get(tool_input, EL_STR("path")); _if_result_70 = (threat_score_path(path)); } else { _if_result_70 = (0); } _if_result_70; })); } _if_result_69; });
|
||||
el_val_t computed_tool_score = ({ el_val_t _if_result_109 = 0; if (str_eq(tool_name, EL_STR("run_command"))) { el_val_t cmd = json_get(tool_input, EL_STR("command")); _if_result_109 = (threat_score_command(cmd)); } else { _if_result_109 = (({ el_val_t _if_result_110 = 0; if ((str_eq(tool_name, EL_STR("write_file")) || str_eq(tool_name, EL_STR("edit_file")))) { el_val_t path = json_get(tool_input, EL_STR("path")); _if_result_110 = (threat_score_path(path)); } else { _if_result_110 = (0); } _if_result_110; })); } _if_result_109; });
|
||||
el_val_t history_score = threat_score_history(history);
|
||||
el_val_t history_contrib = (history_score / 3);
|
||||
el_val_t combined = (computed_tool_score + history_contrib);
|
||||
el_val_t should_log = (combined >= 40);
|
||||
if (should_log) {
|
||||
el_val_t ts = time_now();
|
||||
el_val_t authorized_str = ({ el_val_t _if_result_71 = 0; if (security_research_authorized()) { _if_result_71 = (EL_STR("true")); } else { _if_result_71 = (EL_STR("false")); } _if_result_71; });
|
||||
el_val_t authorized_str = ({ el_val_t _if_result_111 = 0; if (security_research_authorized()) { _if_result_111 = (EL_STR("true")); } else { _if_result_111 = (EL_STR("false")); } _if_result_111; });
|
||||
el_val_t log_content = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"event\":\"threat_check\",\"tool\":\""), tool_name), EL_STR("\",\"score\":")), int_to_str(combined)), EL_STR(",\"tool_score\":")), int_to_str(computed_tool_score)), EL_STR(",\"history_score\":")), int_to_str(history_score)), EL_STR(",\"authorized\":")), authorized_str), EL_STR(",\"ts\":")), int_to_str(ts)), EL_STR("}"));
|
||||
el_val_t log_tags = EL_STR("[\"security-audit\",\"threat-check\"]");
|
||||
el_val_t discard = mem_remember(log_content, log_tags);
|
||||
@@ -610,7 +758,7 @@ el_val_t threat_history_append(el_val_t text) {
|
||||
el_val_t safe_text = str_to_lower(text);
|
||||
el_val_t combined = el_str_concat(el_str_concat(current, EL_STR(" ")), safe_text);
|
||||
el_val_t len = str_len(combined);
|
||||
el_val_t trimmed = ({ el_val_t _if_result_72 = 0; if ((len > 2000)) { _if_result_72 = (str_slice(combined, (len - 2000), len)); } else { _if_result_72 = (combined); } _if_result_72; });
|
||||
el_val_t trimmed = ({ el_val_t _if_result_112 = 0; if ((len > 2000)) { _if_result_112 = (str_slice(combined, (len - 2000), len)); } else { _if_result_112 = (combined); } _if_result_112; });
|
||||
state_set(EL_STR("agentic_conv_history"), trimmed);
|
||||
return 0;
|
||||
}
|
||||
|
||||
+89
-70
@@ -5,6 +5,15 @@ el_val_t add_punct(el_val_t s, el_val_t intent);
|
||||
el_val_t add_to_seen(el_val_t seen, el_val_t node_id);
|
||||
el_val_t aff_try_slot(el_val_t slot_json, el_val_t aff_7d_ts, el_val_t acc_key);
|
||||
el_val_t affective_context_prefix(void);
|
||||
el_val_t is_utility_request(el_val_t body, el_val_t session_id);
|
||||
el_val_t operator_identity_block(void);
|
||||
el_val_t provenance_add_sources(el_val_t block, el_val_t btype, el_val_t has_cit, el_val_t cit_raw, el_val_t acc);
|
||||
el_val_t provenance_names(el_val_t tools_used);
|
||||
el_val_t provenance_scan_urls(el_val_t arr, el_val_t acc);
|
||||
el_val_t text_join_sep(el_val_t accumulated, el_val_t incoming, el_val_t after_interruption);
|
||||
el_val_t receipt_rule(void);
|
||||
el_val_t receipt_strip(el_val_t s);
|
||||
el_val_t tool_receipt(el_val_t tools_used, el_val_t sources);
|
||||
el_val_t agent_number(el_val_t agent);
|
||||
el_val_t agent_person(el_val_t agent);
|
||||
el_val_t agent_workspace_root(void);
|
||||
@@ -20,8 +29,8 @@ el_val_t akk_alaku_present(el_val_t slot);
|
||||
el_val_t akk_amaru_perfect(el_val_t slot);
|
||||
el_val_t akk_amaru_present(el_val_t slot);
|
||||
el_val_t akk_amaru_stative(el_val_t slot);
|
||||
el_val_t akk_conjugate(el_val_t verb, el_val_t tense, el_val_t person, el_val_t number);
|
||||
el_val_t akk_conjugate_copula(el_val_t tense, el_val_t slot);
|
||||
el_val_t akk_conjugate(el_val_t verb, el_val_t tense, el_val_t person, el_val_t number);
|
||||
el_val_t akk_copula_present(el_val_t slot);
|
||||
el_val_t akk_copula_stative(el_val_t slot);
|
||||
el_val_t akk_decline(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
@@ -39,25 +48,25 @@ el_val_t akk_qabu_stative(el_val_t slot);
|
||||
el_val_t akk_regular_perfect(el_val_t stem, el_val_t slot);
|
||||
el_val_t akk_regular_present(el_val_t stem, el_val_t slot);
|
||||
el_val_t akk_regular_stative(el_val_t stem, el_val_t slot);
|
||||
el_val_t akk_slot(el_val_t person, el_val_t number);
|
||||
el_val_t akk_slot_g(el_val_t person, el_val_t gender, el_val_t number);
|
||||
el_val_t akk_slot(el_val_t person, el_val_t number);
|
||||
el_val_t akk_str_drop_last(el_val_t s, el_val_t n);
|
||||
el_val_t akk_str_ends(el_val_t s, el_val_t suf);
|
||||
el_val_t akk_str_len(el_val_t s);
|
||||
el_val_t akk_strip_nom(el_val_t noun);
|
||||
el_val_t ang_article(el_val_t gender, el_val_t gram_case, el_val_t number);
|
||||
el_val_t ang_article_feminine(el_val_t gram_case, el_val_t number);
|
||||
el_val_t ang_article_masculine(el_val_t gram_case, el_val_t number);
|
||||
el_val_t ang_article_neuter(el_val_t gram_case, el_val_t number);
|
||||
el_val_t ang_article(el_val_t gender, el_val_t gram_case, el_val_t number);
|
||||
el_val_t ang_beon_present(el_val_t slot);
|
||||
el_val_t ang_conjugate(el_val_t verb, el_val_t tense, el_val_t person, el_val_t number);
|
||||
el_val_t ang_cuman_past(el_val_t slot);
|
||||
el_val_t ang_cuman_present(el_val_t slot);
|
||||
el_val_t ang_declension(el_val_t noun, el_val_t gender);
|
||||
el_val_t ang_decline(el_val_t noun, el_val_t gram_case, el_val_t number, el_val_t gender);
|
||||
el_val_t ang_decline_strong_masc(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t ang_decline_strong_neut(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t ang_decline_weak(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t ang_decline(el_val_t noun, el_val_t gram_case, el_val_t number, el_val_t gender);
|
||||
el_val_t ang_don_past(el_val_t slot);
|
||||
el_val_t ang_don_present(el_val_t slot);
|
||||
el_val_t ang_gan_past(el_val_t slot);
|
||||
@@ -76,10 +85,10 @@ el_val_t ang_seon_present(el_val_t slot);
|
||||
el_val_t ang_slot(el_val_t person, el_val_t number);
|
||||
el_val_t ang_str_drop_last(el_val_t s, el_val_t n);
|
||||
el_val_t ang_str_ends(el_val_t s, el_val_t suf);
|
||||
el_val_t ang_str_last2(el_val_t s);
|
||||
el_val_t ang_str_last_char(el_val_t s);
|
||||
el_val_t ang_weak_past(el_val_t stem, el_val_t slot);
|
||||
el_val_t ang_str_last2(el_val_t s);
|
||||
el_val_t ang_weak_past_stem(el_val_t stem);
|
||||
el_val_t ang_weak_past(el_val_t stem, el_val_t slot);
|
||||
el_val_t ang_weak_present_ending(el_val_t slot);
|
||||
el_val_t ang_weak_stem(el_val_t verb);
|
||||
el_val_t ang_wesan_past(el_val_t slot);
|
||||
@@ -88,8 +97,8 @@ el_val_t ang_willan_past(el_val_t slot);
|
||||
el_val_t ang_willan_present(el_val_t slot);
|
||||
el_val_t ang_witan_past(el_val_t slot);
|
||||
el_val_t ang_witan_present(el_val_t slot);
|
||||
el_val_t api_err(el_val_t msg);
|
||||
el_val_t api_err_protected(el_val_t id);
|
||||
el_val_t api_err(el_val_t msg);
|
||||
el_val_t api_json_escape(el_val_t s);
|
||||
el_val_t api_nonempty(el_val_t s);
|
||||
el_val_t api_not_persisted(el_val_t id);
|
||||
@@ -99,19 +108,19 @@ el_val_t api_persisted(el_val_t id);
|
||||
el_val_t api_query_int(el_val_t path, el_val_t key, el_val_t default_val);
|
||||
el_val_t api_query_param(el_val_t path, el_val_t key);
|
||||
el_val_t ar_case_ending(el_val_t kase, el_val_t definite);
|
||||
el_val_t ar_conjugate(el_val_t verb, el_val_t tense, el_val_t person, el_val_t gender, el_val_t number);
|
||||
el_val_t ar_conjugate_form1(el_val_t past_base, el_val_t present_stem, el_val_t tense, el_val_t slot);
|
||||
el_val_t ar_conjugate(el_val_t verb, el_val_t tense, el_val_t person, el_val_t gender, el_val_t number);
|
||||
el_val_t ar_definite_article(el_val_t noun);
|
||||
el_val_t ar_gender(el_val_t noun);
|
||||
el_val_t ar_imperfect_prefix(el_val_t slot);
|
||||
el_val_t ar_imperfect_suffix(el_val_t slot);
|
||||
el_val_t ar_irregular(el_val_t verb, el_val_t tense, el_val_t slot);
|
||||
el_val_t ar_irregular_araada(el_val_t slot, el_val_t tense);
|
||||
el_val_t ar_irregular_istata(el_val_t slot, el_val_t tense);
|
||||
el_val_t ar_irregular_jaa(el_val_t slot, el_val_t tense);
|
||||
el_val_t ar_irregular_kaana(el_val_t slot, el_val_t tense);
|
||||
el_val_t ar_irregular_qaala(el_val_t slot, el_val_t tense);
|
||||
el_val_t ar_irregular_raaa(el_val_t slot, el_val_t tense);
|
||||
el_val_t ar_irregular(el_val_t verb, el_val_t tense, el_val_t slot);
|
||||
el_val_t ar_is_sun_letter(el_val_t c);
|
||||
el_val_t ar_masc_pl_ending(el_val_t kase);
|
||||
el_val_t ar_noun_form(el_val_t noun, el_val_t gender, el_val_t kase, el_val_t number, el_val_t definite);
|
||||
@@ -131,6 +140,7 @@ el_val_t auto_term_try_slot(el_val_t slot_type, el_val_t slot_lbl);
|
||||
el_val_t awareness_run(void);
|
||||
el_val_t axon_get(el_val_t path);
|
||||
el_val_t axon_post(el_val_t path, el_val_t body);
|
||||
el_val_t bounded_persona_floor(void);
|
||||
el_val_t bridge_save(el_val_t session_id, el_val_t model, el_val_t safe_sys, el_val_t tools_json, el_val_t messages, el_val_t tools_log, el_val_t tool_use_id);
|
||||
el_val_t build_form_from_json(el_val_t semantic_form_json, el_val_t lang_code);
|
||||
el_val_t build_np(el_val_t referent, el_val_t slots);
|
||||
@@ -150,8 +160,12 @@ el_val_t cmd_abs_escape_at(el_val_t cmd, el_val_t root, el_val_t needle);
|
||||
el_val_t connectd_get(el_val_t suffix);
|
||||
el_val_t connectd_post(el_val_t suffix, el_val_t body);
|
||||
el_val_t connector_tools_json(void);
|
||||
el_val_t conv_history_load(void);
|
||||
el_val_t conv_history_persist(el_val_t hist);
|
||||
el_val_t conv_hist_key(el_val_t session_id);
|
||||
el_val_t conv_hist_label(el_val_t session_id);
|
||||
el_val_t conv_history_block(el_val_t session_id);
|
||||
el_val_t conv_history_load(el_val_t session_id);
|
||||
el_val_t conv_history_persist(el_val_t session_id, el_val_t hist);
|
||||
el_val_t conv_history_record(el_val_t session_id, el_val_t user_msg, el_val_t assistant_msg, el_val_t receipt);
|
||||
el_val_t cop_article(el_val_t gender, el_val_t number, el_val_t definite);
|
||||
el_val_t cop_bwk_future(el_val_t prefix);
|
||||
el_val_t cop_bwk_perfect(el_val_t prefix);
|
||||
@@ -173,8 +187,8 @@ el_val_t cop_map_canonical(el_val_t verb);
|
||||
el_val_t cop_nau_future(el_val_t prefix);
|
||||
el_val_t cop_nau_perfect(el_val_t prefix);
|
||||
el_val_t cop_nau_present(el_val_t prefix);
|
||||
el_val_t cop_noun_phrase(el_val_t noun, el_val_t gram_case, el_val_t number, el_val_t definite);
|
||||
el_val_t cop_noun_phrase_gendered(el_val_t noun, el_val_t gram_case, el_val_t number, el_val_t definite, el_val_t gender);
|
||||
el_val_t cop_noun_phrase(el_val_t noun, el_val_t gram_case, el_val_t number, el_val_t definite);
|
||||
el_val_t cop_regular_future(el_val_t prefix, el_val_t stem);
|
||||
el_val_t cop_regular_perfect(el_val_t prefix, el_val_t stem);
|
||||
el_val_t cop_regular_present(el_val_t prefix, el_val_t stem);
|
||||
@@ -184,16 +198,16 @@ el_val_t cop_shwpe_present(el_val_t prefix);
|
||||
el_val_t cop_slot(el_val_t person, el_val_t number);
|
||||
el_val_t cop_str_ends(el_val_t s, el_val_t suf);
|
||||
el_val_t cop_str_len(el_val_t s);
|
||||
el_val_t cop_subject_prefix(el_val_t person, el_val_t number);
|
||||
el_val_t cop_subject_prefix_gendered(el_val_t person, el_val_t gender, el_val_t number);
|
||||
el_val_t cop_subject_prefix(el_val_t person, el_val_t number);
|
||||
el_val_t current_engine_note(el_val_t model);
|
||||
el_val_t de_adj_ending(el_val_t gender, el_val_t gram_case, el_val_t number, el_val_t article_type);
|
||||
el_val_t de_article(el_val_t gender, el_val_t gram_case, el_val_t number, el_val_t definite);
|
||||
el_val_t de_article_def(el_val_t gender, el_val_t gram_case, el_val_t number);
|
||||
el_val_t de_article_indef(el_val_t gender, el_val_t gram_case, el_val_t number);
|
||||
el_val_t de_article(el_val_t gender, el_val_t gram_case, el_val_t number, el_val_t definite);
|
||||
el_val_t de_case_ending(el_val_t noun, el_val_t gender, el_val_t gram_case, el_val_t number);
|
||||
el_val_t de_conjugate(el_val_t verb, el_val_t tense, el_val_t person, el_val_t number);
|
||||
el_val_t de_conjugate_weak(el_val_t stem, el_val_t tense, el_val_t person, el_val_t number);
|
||||
el_val_t de_conjugate(el_val_t verb, el_val_t tense, el_val_t person, el_val_t number);
|
||||
el_val_t de_irregular_present(el_val_t verb, el_val_t person, el_val_t number);
|
||||
el_val_t de_norm_number(el_val_t number);
|
||||
el_val_t de_norm_person(el_val_t person);
|
||||
@@ -203,15 +217,12 @@ el_val_t dharma_network_state(void);
|
||||
el_val_t dharma_registry(void);
|
||||
el_val_t dispatch_tool(el_val_t tool_name, el_val_t tool_input);
|
||||
el_val_t distill_transcript(el_val_t transcript);
|
||||
el_val_t egy_conjugate_copula(el_val_t tense, el_val_t slot);
|
||||
el_val_t egy_conjugate_pronoun(el_val_t person, el_val_t number);
|
||||
el_val_t egy_conjugate(el_val_t verb, el_val_t tense, el_val_t person, el_val_t number);
|
||||
el_val_t egy_Dd_future(el_val_t slot);
|
||||
el_val_t egy_Dd_past(el_val_t slot);
|
||||
el_val_t egy_Dd_present(el_val_t slot);
|
||||
el_val_t egy_Sm_future(el_val_t slot);
|
||||
el_val_t egy_Sm_past(el_val_t slot);
|
||||
el_val_t egy_Sm_present(el_val_t slot);
|
||||
el_val_t egy_conjugate(el_val_t verb, el_val_t tense, el_val_t person, el_val_t number);
|
||||
el_val_t egy_conjugate_copula(el_val_t tense, el_val_t slot);
|
||||
el_val_t egy_conjugate_pronoun(el_val_t person, el_val_t number);
|
||||
el_val_t egy_decline(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t egy_drop(el_val_t s, el_val_t n);
|
||||
el_val_t egy_fem(el_val_t noun);
|
||||
@@ -235,8 +246,11 @@ el_val_t egy_regular_present(el_val_t stem, el_val_t slot);
|
||||
el_val_t egy_sdm_future(el_val_t slot);
|
||||
el_val_t egy_sdm_past(el_val_t slot);
|
||||
el_val_t egy_sdm_present(el_val_t slot);
|
||||
el_val_t egy_slot(el_val_t person, el_val_t number);
|
||||
el_val_t egy_slot_with_gender(el_val_t person, el_val_t gender, el_val_t number);
|
||||
el_val_t egy_slot(el_val_t person, el_val_t number);
|
||||
el_val_t egy_Sm_future(el_val_t slot);
|
||||
el_val_t egy_Sm_past(el_val_t slot);
|
||||
el_val_t egy_Sm_present(el_val_t slot);
|
||||
el_val_t egy_str_ends(el_val_t s, el_val_t suf);
|
||||
el_val_t egy_str_len(el_val_t s);
|
||||
el_val_t egy_suffix_pronoun(el_val_t slot);
|
||||
@@ -257,9 +271,9 @@ el_val_t en_verb_3sg(el_val_t base);
|
||||
el_val_t en_verb_form(el_val_t base, el_val_t tense, el_val_t person, el_val_t number);
|
||||
el_val_t en_verb_gerund(el_val_t base);
|
||||
el_val_t en_verb_past(el_val_t base);
|
||||
el_val_t engram_compile(el_val_t intent);
|
||||
el_val_t engram_compile_multi(el_val_t topic);
|
||||
el_val_t engram_compile_ranked(el_val_t nodes_json, el_val_t max_nodes);
|
||||
el_val_t engram_compile(el_val_t intent);
|
||||
el_val_t engram_dedup_nodes(el_val_t nodes_json);
|
||||
el_val_t engram_detect_recall_intent(el_val_t message);
|
||||
el_val_t engram_extract_entities(el_val_t message);
|
||||
@@ -325,9 +339,9 @@ el_val_t es_starts_with_stressed_a(el_val_t noun);
|
||||
el_val_t es_stem(el_val_t base);
|
||||
el_val_t es_str_drop_last(el_val_t s, el_val_t n);
|
||||
el_val_t es_str_ends(el_val_t s, el_val_t suf);
|
||||
el_val_t es_str_last_char(el_val_t s);
|
||||
el_val_t es_str_last2(el_val_t s);
|
||||
el_val_t es_str_last3(el_val_t s);
|
||||
el_val_t es_str_last_char(el_val_t s);
|
||||
el_val_t es_verb_class(el_val_t base);
|
||||
el_val_t extract_dim(el_val_t content, el_val_t key);
|
||||
el_val_t fi_apply_case(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
@@ -370,8 +384,8 @@ el_val_t fr_slot(el_val_t person, el_val_t number);
|
||||
el_val_t fr_stem(el_val_t base);
|
||||
el_val_t fr_str_drop_last(el_val_t s, el_val_t n);
|
||||
el_val_t fr_str_ends(el_val_t s, el_val_t suf);
|
||||
el_val_t fr_str_last2(el_val_t s);
|
||||
el_val_t fr_str_last_char(el_val_t s);
|
||||
el_val_t fr_str_last2(el_val_t s);
|
||||
el_val_t fr_subject_starts_vowel(el_val_t subject);
|
||||
el_val_t fr_uses_etre(el_val_t verb);
|
||||
el_val_t fr_verb_ends_vowel(el_val_t verb_form);
|
||||
@@ -393,9 +407,9 @@ el_val_t fro_conj3_future(el_val_t verb, el_val_t slot);
|
||||
el_val_t fro_conj3_past(el_val_t stem, el_val_t slot);
|
||||
el_val_t fro_conj3_present(el_val_t stem, el_val_t slot);
|
||||
el_val_t fro_conjugate(el_val_t verb, el_val_t tense, el_val_t person, el_val_t number);
|
||||
el_val_t fro_decline(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t fro_decline_fem(el_val_t noun, el_val_t number);
|
||||
el_val_t fro_decline_masc(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t fro_decline(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t fro_drop(el_val_t s, el_val_t n);
|
||||
el_val_t fro_estre_future(el_val_t slot);
|
||||
el_val_t fro_estre_past(el_val_t slot);
|
||||
@@ -413,15 +427,15 @@ el_val_t fro_venir_past(el_val_t slot);
|
||||
el_val_t fro_venir_present(el_val_t slot);
|
||||
el_val_t fro_verb_class(el_val_t verb);
|
||||
el_val_t fro_verb_stem(el_val_t verb, el_val_t vclass);
|
||||
el_val_t generate(el_val_t semantic_form_json);
|
||||
el_val_t generate_frame(el_val_t frame);
|
||||
el_val_t generate_frame_lang(el_val_t frame, el_val_t lang_code);
|
||||
el_val_t generate_frame(el_val_t frame);
|
||||
el_val_t generate_lang(el_val_t semantic_form_json, el_val_t lang_code);
|
||||
el_val_t generate_tree(el_val_t rule_id_str, el_val_t slots);
|
||||
el_val_t generate(el_val_t semantic_form_json);
|
||||
el_val_t get_rules(void);
|
||||
el_val_t get_vocab(void);
|
||||
el_val_t gez_conjugate(el_val_t verb, el_val_t tense, el_val_t person, el_val_t number);
|
||||
el_val_t gez_conjugate_copula(el_val_t tense, el_val_t slot);
|
||||
el_val_t gez_conjugate(el_val_t verb, el_val_t tense, el_val_t person, el_val_t number);
|
||||
el_val_t gez_decline(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t gez_generic_imperfect(el_val_t base3sg, el_val_t slot);
|
||||
el_val_t gez_generic_perfect(el_val_t base3sg, el_val_t slot);
|
||||
@@ -440,13 +454,12 @@ el_val_t gez_qwl_imperfect(el_val_t slot);
|
||||
el_val_t gez_qwl_perfect(el_val_t slot);
|
||||
el_val_t gez_ray_imperfect(el_val_t slot);
|
||||
el_val_t gez_ray_perfect(el_val_t slot);
|
||||
el_val_t gez_slot(el_val_t person, el_val_t number);
|
||||
el_val_t gez_slot_g(el_val_t person, el_val_t gender, el_val_t number);
|
||||
el_val_t gez_slot(el_val_t person, el_val_t number);
|
||||
el_val_t gez_str_drop_last(el_val_t s, el_val_t n);
|
||||
el_val_t gez_str_ends(el_val_t s, el_val_t suf);
|
||||
el_val_t gez_str_len(el_val_t s);
|
||||
el_val_t goh_conjugate(el_val_t verb, el_val_t tense, el_val_t person, el_val_t number);
|
||||
el_val_t goh_decline(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t goh_decline_fem_o_pl(el_val_t stem, el_val_t gram_case);
|
||||
el_val_t goh_decline_fem_o_sg(el_val_t stem, el_val_t gram_case);
|
||||
el_val_t goh_decline_masc_a_pl(el_val_t stem, el_val_t gram_case);
|
||||
@@ -455,6 +468,7 @@ el_val_t goh_decline_masc_n_pl(el_val_t stem, el_val_t gram_case);
|
||||
el_val_t goh_decline_masc_n_sg(el_val_t stem, el_val_t gram_case);
|
||||
el_val_t goh_decline_neut_a_pl(el_val_t stem, el_val_t gram_case);
|
||||
el_val_t goh_decline_neut_a_sg(el_val_t stem, el_val_t gram_case);
|
||||
el_val_t goh_decline(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t goh_demo_article(el_val_t stype, el_val_t number);
|
||||
el_val_t goh_drop(el_val_t s, el_val_t n);
|
||||
el_val_t goh_extract_stem(el_val_t noun, el_val_t stype);
|
||||
@@ -479,13 +493,13 @@ el_val_t goh_weak_present(el_val_t stem, el_val_t slot);
|
||||
el_val_t goh_wesan_past(el_val_t slot);
|
||||
el_val_t goh_wesan_present(el_val_t slot);
|
||||
el_val_t got_conjugate(el_val_t verb, el_val_t tense, el_val_t person, el_val_t number);
|
||||
el_val_t got_decline(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t got_decline_a_stem_pl(el_val_t stem, el_val_t gram_case);
|
||||
el_val_t got_decline_a_stem_sg(el_val_t stem, el_val_t gram_case);
|
||||
el_val_t got_decline_n_stem_pl(el_val_t stem, el_val_t gram_case);
|
||||
el_val_t got_decline_n_stem_sg(el_val_t stem, el_val_t gram_case);
|
||||
el_val_t got_decline_o_stem_pl(el_val_t stem, el_val_t gram_case);
|
||||
el_val_t got_decline_o_stem_sg(el_val_t stem, el_val_t gram_case);
|
||||
el_val_t got_decline(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t got_demo_article(el_val_t stype);
|
||||
el_val_t got_extract_stem(el_val_t noun, el_val_t stype);
|
||||
el_val_t got_gaggan_past(el_val_t slot);
|
||||
@@ -518,17 +532,17 @@ el_val_t gram_build_vp(el_val_t verb, el_val_t aux, el_val_t profile);
|
||||
el_val_t gram_order_constituents(el_val_t subj, el_val_t verb, el_val_t obj, el_val_t profile);
|
||||
el_val_t gram_question_strategy(el_val_t profile);
|
||||
el_val_t gram_word_order(el_val_t profile);
|
||||
el_val_t grc_article(el_val_t gender, el_val_t gram_case, el_val_t number);
|
||||
el_val_t grc_article_feminine(el_val_t gram_case, el_val_t number);
|
||||
el_val_t grc_article_masculine(el_val_t gram_case, el_val_t number);
|
||||
el_val_t grc_article_neuter(el_val_t gram_case, el_val_t number);
|
||||
el_val_t grc_article(el_val_t gender, el_val_t gram_case, el_val_t number);
|
||||
el_val_t grc_conjugate(el_val_t verb, el_val_t tense, el_val_t person, el_val_t number);
|
||||
el_val_t grc_declension(el_val_t noun);
|
||||
el_val_t grc_decline(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t grc_decline_1a(el_val_t stem, el_val_t gram_case, el_val_t number);
|
||||
el_val_t grc_decline_1e(el_val_t stem, el_val_t gram_case, el_val_t number);
|
||||
el_val_t grc_decline_2m(el_val_t stem, el_val_t gram_case, el_val_t number);
|
||||
el_val_t grc_decline_2n(el_val_t stem, el_val_t gram_case, el_val_t number);
|
||||
el_val_t grc_decline(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t grc_echein_aorist(el_val_t slot);
|
||||
el_val_t grc_echein_future(el_val_t slot);
|
||||
el_val_t grc_echein_imperfect(el_val_t slot);
|
||||
@@ -555,9 +569,9 @@ el_val_t grc_present_stem(el_val_t verb);
|
||||
el_val_t grc_slot(el_val_t person, el_val_t number);
|
||||
el_val_t grc_str_drop_last(el_val_t s, el_val_t n);
|
||||
el_val_t grc_str_ends(el_val_t s, el_val_t suf);
|
||||
el_val_t grc_str_last_char(el_val_t s);
|
||||
el_val_t grc_str_last2(el_val_t s);
|
||||
el_val_t grc_str_last3(el_val_t s);
|
||||
el_val_t grc_str_last_char(el_val_t s);
|
||||
el_val_t grc_thematic_future_ending(el_val_t slot);
|
||||
el_val_t grc_thematic_imperfect_ending(el_val_t slot);
|
||||
el_val_t grc_thematic_present_ending(el_val_t slot);
|
||||
@@ -589,17 +603,17 @@ el_val_t handle_api_recall(el_val_t method, el_val_t path, el_val_t body);
|
||||
el_val_t handle_api_remember(el_val_t body);
|
||||
el_val_t handle_api_search_knowledge(el_val_t method, el_val_t path, el_val_t body);
|
||||
el_val_t handle_api_tune_config(el_val_t body);
|
||||
el_val_t handle_chat(el_val_t body);
|
||||
el_val_t handle_chat_agentic(el_val_t body);
|
||||
el_val_t handle_chat_as_soul(el_val_t body);
|
||||
el_val_t handle_chat_plan(el_val_t body);
|
||||
el_val_t handle_chat(el_val_t body);
|
||||
el_val_t handle_config(el_val_t method, el_val_t body);
|
||||
el_val_t handle_connectors(el_val_t method, el_val_t clean, el_val_t body);
|
||||
el_val_t handle_conversations(el_val_t method);
|
||||
el_val_t handle_dharma(el_val_t path, el_val_t method, el_val_t body);
|
||||
el_val_t handle_dharma_recv(el_val_t body);
|
||||
el_val_t handle_dharma_room_turn(el_val_t body);
|
||||
el_val_t handle_dharma_room_turn_agentic(el_val_t body);
|
||||
el_val_t handle_dharma_room_turn(el_val_t body);
|
||||
el_val_t handle_dharma(el_val_t path, el_val_t method, el_val_t body);
|
||||
el_val_t handle_elp_chat(el_val_t body);
|
||||
el_val_t handle_nlg(el_val_t path, el_val_t method, el_val_t body);
|
||||
el_val_t handle_request(el_val_t method, el_val_t path, el_val_t body);
|
||||
@@ -607,11 +621,11 @@ el_val_t handle_safety_contact_get(void);
|
||||
el_val_t handle_safety_contact_post(el_val_t body);
|
||||
el_val_t handle_see(el_val_t body);
|
||||
el_val_t handle_session_approve(el_val_t session_id, el_val_t body);
|
||||
el_val_t handle_tool(el_val_t path, el_val_t method, el_val_t body);
|
||||
el_val_t handle_tool_result(el_val_t session_id, el_val_t body);
|
||||
el_val_t handle_tool(el_val_t path, el_val_t method, el_val_t body);
|
||||
el_val_t hard_bell_threshold(void);
|
||||
el_val_t he_conjugate(el_val_t verb, el_val_t tense, el_val_t person, el_val_t gender, el_val_t number);
|
||||
el_val_t he_conjugate_copula(el_val_t tense, el_val_t slot);
|
||||
el_val_t he_conjugate(el_val_t verb, el_val_t tense, el_val_t person, el_val_t gender, el_val_t number);
|
||||
el_val_t he_copula_future(el_val_t slot);
|
||||
el_val_t he_copula_past(el_val_t slot);
|
||||
el_val_t he_definite_prefix(el_val_t noun);
|
||||
@@ -648,12 +662,12 @@ el_val_t hi_genitive_phrase(el_val_t possessor, el_val_t possessor_gender, el_va
|
||||
el_val_t hi_hona_past(el_val_t gender, el_val_t number);
|
||||
el_val_t hi_hona_present(el_val_t person, el_val_t number);
|
||||
el_val_t hi_masc_aa_stem(el_val_t noun);
|
||||
el_val_t hi_noun_direct(el_val_t noun, el_val_t gender, el_val_t number);
|
||||
el_val_t hi_noun_direct_f(el_val_t noun, el_val_t number);
|
||||
el_val_t hi_noun_direct_m(el_val_t noun, el_val_t number);
|
||||
el_val_t hi_noun_oblique(el_val_t noun, el_val_t gender, el_val_t number);
|
||||
el_val_t hi_noun_direct(el_val_t noun, el_val_t gender, el_val_t number);
|
||||
el_val_t hi_noun_oblique_f(el_val_t noun, el_val_t number);
|
||||
el_val_t hi_noun_oblique_m(el_val_t noun, el_val_t number);
|
||||
el_val_t hi_noun_oblique(el_val_t noun, el_val_t gender, el_val_t number);
|
||||
el_val_t hi_noun_with_post(el_val_t noun, el_val_t gender, el_val_t number, el_val_t gram_case);
|
||||
el_val_t hi_past_irregular(el_val_t stem, el_val_t gender, el_val_t number);
|
||||
el_val_t hi_past_suffix(el_val_t gender, el_val_t number);
|
||||
@@ -663,11 +677,11 @@ el_val_t hi_str_drop_last(el_val_t s, el_val_t n);
|
||||
el_val_t hi_str_ends(el_val_t s, el_val_t suf);
|
||||
el_val_t hi_str_last_char(el_val_t s);
|
||||
el_val_t hi_tense_suffix(el_val_t tense, el_val_t gender, el_val_t number);
|
||||
el_val_t hi_verb_stem(el_val_t infinitive);
|
||||
el_val_t hi_verb_stem_clean(el_val_t infinitive);
|
||||
el_val_t hi_verb_stem(el_val_t infinitive);
|
||||
el_val_t hist_append(el_val_t hist, el_val_t role, el_val_t content);
|
||||
el_val_t hist_trim(el_val_t hist);
|
||||
el_val_t hist_trim_with_bell_guard(el_val_t hist);
|
||||
el_val_t hist_trim(el_val_t hist);
|
||||
el_val_t id_in_seen(el_val_t node_id, el_val_t seen);
|
||||
el_val_t idle_count(void);
|
||||
el_val_t idle_inc(void);
|
||||
@@ -698,7 +712,6 @@ el_val_t json_escape(el_val_t s);
|
||||
el_val_t json_safe(el_val_t s);
|
||||
el_val_t la_conjugate(el_val_t verb, el_val_t tense, el_val_t person, el_val_t number);
|
||||
el_val_t la_declension(el_val_t noun);
|
||||
el_val_t la_decline(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t la_decline_1(el_val_t stem, el_val_t gram_case, el_val_t number);
|
||||
el_val_t la_decline_2er(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t la_decline_2m(el_val_t stem, el_val_t gram_case, el_val_t number);
|
||||
@@ -706,6 +719,7 @@ el_val_t la_decline_2n(el_val_t stem, el_val_t gram_case, el_val_t number);
|
||||
el_val_t la_decline_3(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t la_decline_4(el_val_t stem, el_val_t gram_case, el_val_t number);
|
||||
el_val_t la_decline_5(el_val_t stem, el_val_t gram_case, el_val_t number);
|
||||
el_val_t la_decline(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t la_esse_future(el_val_t slot);
|
||||
el_val_t la_esse_past(el_val_t slot);
|
||||
el_val_t la_esse_present(el_val_t slot);
|
||||
@@ -729,9 +743,9 @@ el_val_t la_slot(el_val_t person, el_val_t number);
|
||||
el_val_t la_stem(el_val_t verb, el_val_t vclass);
|
||||
el_val_t la_str_drop_last(el_val_t s, el_val_t n);
|
||||
el_val_t la_str_ends(el_val_t s, el_val_t suf);
|
||||
el_val_t la_str_last_char(el_val_t s);
|
||||
el_val_t la_str_last2(el_val_t s);
|
||||
el_val_t la_str_last3(el_val_t s);
|
||||
el_val_t la_str_last_char(el_val_t s);
|
||||
el_val_t la_velle_future(el_val_t slot);
|
||||
el_val_t la_velle_past(el_val_t slot);
|
||||
el_val_t la_velle_present(el_val_t slot);
|
||||
@@ -748,7 +762,6 @@ el_val_t lang_is_fusional(el_val_t profile);
|
||||
el_val_t lang_is_isolating(el_val_t profile);
|
||||
el_val_t lang_is_polysynthetic(el_val_t profile);
|
||||
el_val_t lang_is_rtl(el_val_t profile);
|
||||
el_val_t lang_profile(el_val_t code, el_val_t word_order, el_val_t morph_type, el_val_t has_case, el_val_t has_gender, el_val_t script_dir, el_val_t agreement, el_val_t null_subject);
|
||||
el_val_t lang_profile_akk(void);
|
||||
el_val_t lang_profile_ang(void);
|
||||
el_val_t lang_profile_ar(void);
|
||||
@@ -780,8 +793,10 @@ el_val_t lang_profile_sw(void);
|
||||
el_val_t lang_profile_txb(void);
|
||||
el_val_t lang_profile_uga(void);
|
||||
el_val_t lang_profile_zh(void);
|
||||
el_val_t lang_profile(el_val_t code, el_val_t word_order, el_val_t morph_type, el_val_t has_case, el_val_t has_gender, el_val_t script_dir, el_val_t agreement, el_val_t null_subject);
|
||||
el_val_t lang_word_order(el_val_t profile);
|
||||
el_val_t layered_cycle(el_val_t raw_input);
|
||||
el_val_t layered_cycle(el_val_t raw_input, el_val_t session_id, el_val_t utility);
|
||||
el_val_t layered_generate(el_val_t prompt, el_val_t imprint_id, el_val_t session_id);
|
||||
el_val_t lex_class(el_val_t entry);
|
||||
el_val_t lex_form(el_val_t entry, el_val_t idx);
|
||||
el_val_t lex_pos(el_val_t entry);
|
||||
@@ -820,6 +835,8 @@ el_val_t mem_save(el_val_t path);
|
||||
el_val_t mem_search(el_val_t query, el_val_t limit);
|
||||
el_val_t mem_store(el_val_t content, el_val_t label, el_val_t tags);
|
||||
el_val_t mem_strengthen(el_val_t node_id);
|
||||
el_val_t mem_tombstone(el_val_t node_id);
|
||||
el_val_t memory_hide_tombstoned(el_val_t raw, el_val_t path);
|
||||
el_val_t morph_apply_suffix(el_val_t base, el_val_t suffix);
|
||||
el_val_t morph_conjugate(el_val_t verb, el_val_t tense, el_val_t person, el_val_t number, el_val_t profile);
|
||||
el_val_t morph_inflect(el_val_t word, el_val_t features, el_val_t profile);
|
||||
@@ -828,10 +845,10 @@ el_val_t morph_pluralize(el_val_t noun, el_val_t profile);
|
||||
el_val_t next_bridge_id(void);
|
||||
el_val_t nlg_is_ws(el_val_t c);
|
||||
el_val_t non_conjugate(el_val_t verb, el_val_t tense, el_val_t person, el_val_t number);
|
||||
el_val_t non_decline(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t non_decline_fem(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t non_decline_masc(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t non_decline_neut(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t non_decline(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t non_def_suffix_fem(el_val_t gram_case, el_val_t number);
|
||||
el_val_t non_def_suffix_masc(el_val_t gram_case, el_val_t number);
|
||||
el_val_t non_def_suffix_neut(el_val_t gram_case, el_val_t number);
|
||||
@@ -865,8 +882,8 @@ el_val_t peo_ah_present(el_val_t slot);
|
||||
el_val_t peo_conjugate(el_val_t verb, el_val_t tense, el_val_t person, el_val_t number);
|
||||
el_val_t peo_da_past(el_val_t slot);
|
||||
el_val_t peo_da_present(el_val_t slot);
|
||||
el_val_t peo_decline(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t peo_decline_astem(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t peo_decline(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t peo_drop(el_val_t s, el_val_t n);
|
||||
el_val_t peo_ends(el_val_t s, el_val_t suf);
|
||||
el_val_t peo_kar_past(el_val_t slot);
|
||||
@@ -882,11 +899,11 @@ el_val_t perceive(void);
|
||||
el_val_t pi_aorist_ending(el_val_t slot);
|
||||
el_val_t pi_atthi_present(el_val_t slot);
|
||||
el_val_t pi_conjugate(el_val_t verb, el_val_t tense, el_val_t person, el_val_t number);
|
||||
el_val_t pi_decline(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t pi_decline_a_fem_pl(el_val_t stem, el_val_t gram_case);
|
||||
el_val_t pi_decline_a_fem_sg(el_val_t stem, el_val_t gram_case);
|
||||
el_val_t pi_decline_a_masc_pl(el_val_t stem, el_val_t gram_case);
|
||||
el_val_t pi_decline_a_masc_sg(el_val_t stem, el_val_t gram_case);
|
||||
el_val_t pi_decline(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t pi_detect_class(el_val_t noun);
|
||||
el_val_t pi_drop(el_val_t s, el_val_t n);
|
||||
el_val_t pi_future_ending(el_val_t slot);
|
||||
@@ -917,11 +934,11 @@ el_val_t proactive_curiosity(void);
|
||||
el_val_t pulse_count(void);
|
||||
el_val_t pulse_inc(void);
|
||||
el_val_t rate_limit_check(el_val_t ip, el_val_t path);
|
||||
el_val_t realize(el_val_t form);
|
||||
el_val_t realize_lang(el_val_t form, el_val_t profile);
|
||||
el_val_t realize_np(el_val_t referent, el_val_t number);
|
||||
el_val_t realize_question_lang(el_val_t predicate, el_val_t tense, el_val_t aspect, el_val_t person, el_val_t number, el_val_t agent, el_val_t patient, el_val_t location, el_val_t profile);
|
||||
el_val_t realize_vp_lang(el_val_t base_verb, el_val_t tense, el_val_t aspect, el_val_t person, el_val_t number, el_val_t profile);
|
||||
el_val_t realize(el_val_t form);
|
||||
el_val_t record(el_val_t outcome_json);
|
||||
el_val_t render_studio(void);
|
||||
el_val_t render_tree(el_val_t tree);
|
||||
@@ -932,9 +949,9 @@ el_val_t route_imprint_contextual(el_val_t body);
|
||||
el_val_t route_imprint_user(el_val_t body);
|
||||
el_val_t route_lineage(void);
|
||||
el_val_t route_synthesize(el_val_t body);
|
||||
el_val_t ru_conjugate(el_val_t verb, el_val_t tense, el_val_t person, el_val_t number, el_val_t gender);
|
||||
el_val_t ru_conjugate_1st(el_val_t stem, el_val_t tense, el_val_t person, el_val_t number);
|
||||
el_val_t ru_conjugate_2nd(el_val_t stem, el_val_t tense, el_val_t person, el_val_t number);
|
||||
el_val_t ru_conjugate(el_val_t verb, el_val_t tense, el_val_t person, el_val_t number, el_val_t gender);
|
||||
el_val_t ru_decline_fem(el_val_t noun, el_val_t stype, el_val_t gram_case, el_val_t number);
|
||||
el_val_t ru_decline_masc(el_val_t noun, el_val_t stype, el_val_t gram_case, el_val_t number);
|
||||
el_val_t ru_decline_neut(el_val_t noun, el_val_t stype, el_val_t gram_case, el_val_t number);
|
||||
@@ -947,8 +964,8 @@ el_val_t ru_past_stem(el_val_t verb);
|
||||
el_val_t ru_stem_type(el_val_t noun, el_val_t gender);
|
||||
el_val_t rule_id(el_val_t rule);
|
||||
el_val_t rule_lhs(el_val_t rule);
|
||||
el_val_t rule_rhs(el_val_t rule, el_val_t idx);
|
||||
el_val_t rule_rhs_len(el_val_t rule);
|
||||
el_val_t rule_rhs(el_val_t rule, el_val_t idx);
|
||||
el_val_t run_command_guard(el_val_t cmd, el_val_t root);
|
||||
el_val_t run_command_is_readonly(el_val_t cmd);
|
||||
el_val_t sa_as_future(el_val_t slot);
|
||||
@@ -962,11 +979,11 @@ el_val_t sa_class1_future_ending(el_val_t slot);
|
||||
el_val_t sa_class1_past_ending(el_val_t slot);
|
||||
el_val_t sa_class1_present_ending(el_val_t slot);
|
||||
el_val_t sa_conjugate(el_val_t verb, el_val_t tense, el_val_t person, el_val_t number);
|
||||
el_val_t sa_decline(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t sa_decline_a_stem_pl(el_val_t stem, el_val_t gram_case);
|
||||
el_val_t sa_decline_a_stem_sg(el_val_t stem, el_val_t gram_case);
|
||||
el_val_t sa_decline_aa_stem_pl(el_val_t stem, el_val_t gram_case);
|
||||
el_val_t sa_decline_aa_stem_sg(el_val_t stem, el_val_t gram_case);
|
||||
el_val_t sa_decline(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t sa_drs_future(el_val_t slot);
|
||||
el_val_t sa_drs_past(el_val_t slot);
|
||||
el_val_t sa_drs_present(el_val_t slot);
|
||||
@@ -1014,26 +1031,26 @@ el_val_t scan_token(el_val_t s, el_val_t start);
|
||||
el_val_t security_research_authorized(void);
|
||||
el_val_t seed_persona_from_env(void);
|
||||
el_val_t sem_first_modifier(el_val_t mods);
|
||||
el_val_t sem_frame(el_val_t intent, el_val_t subject, el_val_t obj, el_val_t modifiers);
|
||||
el_val_t sem_frame_lang(el_val_t intent, el_val_t subject, el_val_t obj, el_val_t modifiers, el_val_t lang_code);
|
||||
el_val_t sem_frame_obj(el_val_t intent, el_val_t subject, el_val_t obj);
|
||||
el_val_t sem_frame_simple(el_val_t intent, el_val_t subject);
|
||||
el_val_t sem_frame(el_val_t intent, el_val_t subject, el_val_t obj, el_val_t modifiers);
|
||||
el_val_t sem_get(el_val_t json, el_val_t key);
|
||||
el_val_t sem_intent(el_val_t frame);
|
||||
el_val_t sem_intent_to_realize(el_val_t intent);
|
||||
el_val_t sem_intent(el_val_t frame);
|
||||
el_val_t sem_lang(el_val_t frame);
|
||||
el_val_t sem_modifiers(el_val_t frame);
|
||||
el_val_t sem_object(el_val_t frame);
|
||||
el_val_t sem_realize(el_val_t frame);
|
||||
el_val_t sem_realize_full(el_val_t frame, el_val_t verb, el_val_t tense, el_val_t aspect);
|
||||
el_val_t sem_realize_greet(el_val_t subject);
|
||||
el_val_t sem_realize_lang(el_val_t frame, el_val_t lang_code);
|
||||
el_val_t sem_realize(el_val_t frame);
|
||||
el_val_t sem_subject(el_val_t frame);
|
||||
el_val_t sem_to_spec(el_val_t frame);
|
||||
el_val_t sem_to_spec_full(el_val_t frame, el_val_t verb, el_val_t tense, el_val_t aspect);
|
||||
el_val_t sem_to_spec(el_val_t frame);
|
||||
el_val_t session_auto_title(el_val_t session_id, el_val_t first_message);
|
||||
el_val_t session_create(el_val_t body);
|
||||
el_val_t session_create_cleanup(el_val_t session_id);
|
||||
el_val_t session_create(el_val_t body);
|
||||
el_val_t session_delete(el_val_t session_id);
|
||||
el_val_t session_exists(el_val_t session_id);
|
||||
el_val_t session_get(el_val_t session_id);
|
||||
@@ -1042,11 +1059,11 @@ el_val_t session_hist_save(el_val_t session_id, el_val_t hist);
|
||||
el_val_t session_list(void);
|
||||
el_val_t session_make_content(el_val_t id, el_val_t title, el_val_t created_at, el_val_t updated_at, el_val_t folder);
|
||||
el_val_t session_preload_bullets(el_val_t nodes, el_val_t max_bullets, el_val_t snip_len);
|
||||
el_val_t session_search(el_val_t query);
|
||||
el_val_t session_search_entry(el_val_t node);
|
||||
el_val_t session_search(el_val_t query);
|
||||
el_val_t session_summary_autogenerate(el_val_t hist);
|
||||
el_val_t session_summary_write(el_val_t summary_text);
|
||||
el_val_t session_summary_write_dated(el_val_t summary_text, el_val_t label);
|
||||
el_val_t session_summary_write(el_val_t summary_text);
|
||||
el_val_t session_title_from_message(el_val_t message);
|
||||
el_val_t session_update_meta_timestamp(el_val_t session_id);
|
||||
el_val_t session_update_patch(el_val_t session_id, el_val_t body);
|
||||
@@ -1057,9 +1074,9 @@ el_val_t sga_bith_past(el_val_t slot);
|
||||
el_val_t sga_bith_present(el_val_t slot);
|
||||
el_val_t sga_conjugate(el_val_t verb, el_val_t tense, el_val_t person, el_val_t number);
|
||||
el_val_t sga_copula_present(el_val_t slot);
|
||||
el_val_t sga_decline(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t sga_decline_astem(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t sga_decline_ostem(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t sga_decline(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t sga_detect_gender(el_val_t noun);
|
||||
el_val_t sga_drop(el_val_t s, el_val_t n);
|
||||
el_val_t sga_first(el_val_t s);
|
||||
@@ -1087,9 +1104,9 @@ el_val_t steward_session_check(el_val_t input, el_val_t session_id);
|
||||
el_val_t steward_validate_imprint(el_val_t imprint_id, el_val_t tool_name);
|
||||
el_val_t str_drop_last(el_val_t s, el_val_t n);
|
||||
el_val_t str_ends(el_val_t s, el_val_t suf);
|
||||
el_val_t str_last_char(el_val_t s);
|
||||
el_val_t str_last2(el_val_t s);
|
||||
el_val_t str_last3(el_val_t s);
|
||||
el_val_t str_last_char(el_val_t s);
|
||||
el_val_t strengthen_chat_nodes(el_val_t activation_nodes);
|
||||
el_val_t strip_query(el_val_t path);
|
||||
el_val_t studio_tools_json(void);
|
||||
@@ -1116,8 +1133,8 @@ el_val_t sux_realize_sentence(el_val_t intent, el_val_t agent, el_val_t predicat
|
||||
el_val_t sux_slot(el_val_t person, el_val_t number);
|
||||
el_val_t sux_str_drop_last(el_val_t s, el_val_t n);
|
||||
el_val_t sux_str_ends(el_val_t s, el_val_t suf);
|
||||
el_val_t sux_str_last2(el_val_t s);
|
||||
el_val_t sux_str_last_char(el_val_t s);
|
||||
el_val_t sux_str_last2(el_val_t s);
|
||||
el_val_t sux_tum2_past(el_val_t slot);
|
||||
el_val_t sux_tum2_present(el_val_t slot);
|
||||
el_val_t sux_verb_chain(el_val_t agent, el_val_t verb, el_val_t patient, el_val_t tense);
|
||||
@@ -1135,9 +1152,9 @@ el_val_t sw_noun_plural(el_val_t noun);
|
||||
el_val_t sw_obj_prefix(el_val_t person, el_val_t number, el_val_t noun_class);
|
||||
el_val_t sw_str_drop_last(el_val_t s, el_val_t n);
|
||||
el_val_t sw_str_ends(el_val_t s, el_val_t suf);
|
||||
el_val_t sw_str_first_char(el_val_t s);
|
||||
el_val_t sw_str_first2(el_val_t s);
|
||||
el_val_t sw_str_first3(el_val_t s);
|
||||
el_val_t sw_str_first_char(el_val_t s);
|
||||
el_val_t sw_str_last_char(el_val_t s);
|
||||
el_val_t sw_subj_prefix(el_val_t person, el_val_t number, el_val_t noun_class);
|
||||
el_val_t sw_tense_marker(el_val_t tense);
|
||||
@@ -1151,11 +1168,13 @@ el_val_t threat_trajectory_check(el_val_t tool_name, el_val_t tool_input);
|
||||
el_val_t tier_canonical(void);
|
||||
el_val_t tier_episodic(void);
|
||||
el_val_t tier_working(void);
|
||||
el_val_t tombstone_node(el_val_t id);
|
||||
el_val_t tombstoned_id_set(void);
|
||||
el_val_t tool_auto_approved(el_val_t tool_name);
|
||||
el_val_t txb_conjugate(el_val_t verb, el_val_t tense, el_val_t person, el_val_t number);
|
||||
el_val_t txb_decline(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t txb_decline_fem(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t txb_decline_masc(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t txb_decline(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t txb_detect_gender(el_val_t noun);
|
||||
el_val_t txb_drop(el_val_t s, el_val_t n);
|
||||
el_val_t txb_ends(el_val_t s, el_val_t suf);
|
||||
@@ -1170,8 +1189,8 @@ el_val_t txb_wes_present(el_val_t slot);
|
||||
el_val_t txb_ya_present(el_val_t slot);
|
||||
el_val_t uga_amr_imperfect(el_val_t slot);
|
||||
el_val_t uga_amr_perfect(el_val_t slot);
|
||||
el_val_t uga_conjugate(el_val_t verb, el_val_t tense, el_val_t person, el_val_t number);
|
||||
el_val_t uga_conjugate_copula(el_val_t tense, el_val_t slot);
|
||||
el_val_t uga_conjugate(el_val_t verb, el_val_t tense, el_val_t person, el_val_t number);
|
||||
el_val_t uga_decline(el_val_t noun, el_val_t gram_case, el_val_t number);
|
||||
el_val_t uga_generic_imperfect(el_val_t base3sg, el_val_t slot);
|
||||
el_val_t uga_generic_perfect(el_val_t base3sg, el_val_t slot);
|
||||
@@ -1186,8 +1205,8 @@ el_val_t uga_map_canonical(el_val_t verb);
|
||||
el_val_t uga_noun_phrase(el_val_t noun, el_val_t gram_case, el_val_t number, el_val_t definite);
|
||||
el_val_t uga_ray_imperfect(el_val_t slot);
|
||||
el_val_t uga_ray_perfect(el_val_t slot);
|
||||
el_val_t uga_slot(el_val_t person, el_val_t number);
|
||||
el_val_t uga_slot_g(el_val_t person, el_val_t gender, el_val_t number);
|
||||
el_val_t uga_slot(el_val_t person, el_val_t number);
|
||||
el_val_t uga_str_drop_last(el_val_t s, el_val_t n);
|
||||
el_val_t uga_str_ends(el_val_t s, el_val_t suf);
|
||||
el_val_t uga_str_len(el_val_t s);
|
||||
@@ -1195,6 +1214,6 @@ el_val_t uga_strip_nom(el_val_t noun);
|
||||
el_val_t verb_form(el_val_t base, el_val_t tense, el_val_t person, el_val_t number);
|
||||
el_val_t vocab_by_class(el_val_t cls);
|
||||
el_val_t vocab_by_pos(el_val_t pos);
|
||||
el_val_t vocab_lookup(el_val_t word, el_val_t lang_code);
|
||||
el_val_t vocab_lookup_en(el_val_t word);
|
||||
el_val_t vocab_lookup(el_val_t word, el_val_t lang_code);
|
||||
el_val_t vocab_synonym(el_val_t word, el_val_t lang_register, el_val_t lang_code);
|
||||
|
||||
+27
-1
@@ -169,7 +169,7 @@ el_val_t mem_boot_count_inc(void) {
|
||||
}
|
||||
el_val_t content = el_str_concat(EL_STR("soul:boot_count:"), int_to_str(next));
|
||||
el_val_t tags = EL_STR("[\"soul-meta\",\"boot-counter\"]");
|
||||
el_val_t boot_node_id = engram_node_full(content, EL_STR("Memory"), EL_STR("soul:boot_count"), el_from_float(0.9), el_from_float(0.9), el_from_float(1.0), EL_STR("Canonical"), tags);
|
||||
el_val_t boot_node_id = engram_node_full(content, EL_STR("Memory"), EL_STR("soul:boot_count"), el_from_float(0.55), el_from_float(0.2), el_from_float(1.0), EL_STR("Working"), tags);
|
||||
if (str_eq(boot_node_id, EL_STR(""))) {
|
||||
println(el_str_concat(el_str_concat(EL_STR("[memory] mem_boot_count_inc: write rejected (empty id) \xe2\x80\x94 boot counter node lost (count="), int_to_str(next)), EL_STR(")")));
|
||||
return next;
|
||||
@@ -178,6 +178,32 @@ el_val_t mem_boot_count_inc(void) {
|
||||
if (str_eq(boot_readback, EL_STR("")) || str_eq(boot_readback, EL_STR("{}"))) {
|
||||
println(el_str_concat(el_str_concat(el_str_concat(EL_STR("[memory] mem_boot_count_inc: WRITE VERIFY FAILED id="), boot_node_id), EL_STR(" count=")), int_to_str(next)));
|
||||
}
|
||||
el_val_t wb_url = env(EL_STR("ENGRAM_URL"));
|
||||
el_val_t wb_key = env(EL_STR("ENGRAM_API_KEY"));
|
||||
if (!str_eq(wb_url, EL_STR("")) && !str_eq(wb_key, EL_STR(""))) {
|
||||
el_val_t auth_body = el_str_concat(el_str_concat(EL_STR("{\"_auth\":\""), json_safe(wb_key)), EL_STR("\"}"));
|
||||
el_val_t srv_old = http_get(el_str_concat(wb_url, EL_STR("/api/search?q=soul:boot_count&limit=20")));
|
||||
if (!str_eq(srv_old, EL_STR("")) && !str_eq(srv_old, EL_STR("[]"))) {
|
||||
el_val_t srv_len = json_array_len(srv_old);
|
||||
el_val_t si = 0;
|
||||
while (si < srv_len) {
|
||||
el_val_t srv_node = json_array_get(srv_old, si);
|
||||
el_val_t srv_content = json_get(srv_node, EL_STR("content"));
|
||||
if (str_starts_with(srv_content, EL_STR("soul:boot_count:"))) {
|
||||
el_val_t srv_id = json_get(srv_node, EL_STR("id"));
|
||||
if (!str_eq(srv_id, EL_STR(""))) {
|
||||
http_delete_json(el_str_concat(el_str_concat(wb_url, EL_STR("/api/nodes/")), srv_id), auth_body);
|
||||
}
|
||||
}
|
||||
si = (si + 1);
|
||||
}
|
||||
}
|
||||
el_val_t wb_body = el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"content\":\""), content), EL_STR("\",\"node_type\":\"Memory\",\"label\":\"soul:boot_count\",\"salience\":0.55,\"importance\":0.2,\"tier\":\"Working\",\"tags\":\"[\\\"soul-meta\\\",\\\"boot-counter\\\"]\",\"_auth\":\"")), json_safe(wb_key)), EL_STR("\"}"));
|
||||
el_val_t wb_resp = http_post_json(el_str_concat(wb_url, EL_STR("/api/nodes")), wb_body);
|
||||
if (str_contains(wb_resp, EL_STR("\"error\""))) {
|
||||
println(el_str_concat(EL_STR("[memory] mem_boot_count_inc: HTTP write-back failed (count in-memory only): "), wb_resp));
|
||||
}
|
||||
}
|
||||
return next;
|
||||
return 0;
|
||||
}
|
||||
|
||||
+141
-59
@@ -10,7 +10,6 @@ el_val_t mem_remember(el_val_t content, el_val_t tags);
|
||||
el_val_t mem_recall(el_val_t query, el_val_t depth);
|
||||
el_val_t mem_search(el_val_t query, el_val_t limit);
|
||||
el_val_t mem_strengthen(el_val_t node_id);
|
||||
el_val_t mem_tombstone(el_val_t node_id);
|
||||
el_val_t mem_forget(el_val_t node_id);
|
||||
el_val_t mem_consolidate(void);
|
||||
el_val_t mem_save(el_val_t path);
|
||||
@@ -27,6 +26,11 @@ el_val_t api_ok(el_val_t extra);
|
||||
el_val_t api_err(el_val_t msg);
|
||||
el_val_t api_nonempty(el_val_t s);
|
||||
el_val_t api_or_empty(el_val_t s);
|
||||
el_val_t api_num_or_zero(el_val_t obj, el_val_t key);
|
||||
el_val_t api_utf8_trunc(el_val_t s, el_val_t n);
|
||||
el_val_t api_compact_node(el_val_t node, el_val_t snip);
|
||||
el_val_t api_compact_node_array(el_val_t raw, el_val_t max_items, el_val_t snip);
|
||||
el_val_t api_compact_activated(el_val_t raw, el_val_t max_items, el_val_t snip);
|
||||
el_val_t api_persisted(el_val_t id);
|
||||
el_val_t api_not_persisted(el_val_t id);
|
||||
el_val_t tombstone_node(el_val_t id);
|
||||
@@ -179,6 +183,80 @@ el_val_t api_or_empty(el_val_t s) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
el_val_t api_num_or_zero(el_val_t obj, el_val_t key) {
|
||||
el_val_t v = json_get_raw(obj, key);
|
||||
if (str_eq(v, EL_STR(""))) {
|
||||
return EL_STR("0");
|
||||
}
|
||||
return v;
|
||||
return 0;
|
||||
}
|
||||
|
||||
el_val_t api_utf8_trunc(el_val_t s, el_val_t n) {
|
||||
if (str_len(s) <= n) {
|
||||
return s;
|
||||
}
|
||||
el_val_t cut = n;
|
||||
el_val_t scanning = 1;
|
||||
while (scanning && (cut > 0)) {
|
||||
el_val_t b = str_char_code(s, cut);
|
||||
el_val_t is_cont = ((b >= 128) && (b < 192));
|
||||
cut = ({ el_val_t _if_result_1 = 0; if (is_cont) { _if_result_1 = ((cut - 1)); } else { _if_result_1 = (cut); } _if_result_1; });
|
||||
scanning = is_cont;
|
||||
}
|
||||
return str_slice(s, 0, cut);
|
||||
return 0;
|
||||
}
|
||||
|
||||
el_val_t api_compact_node(el_val_t node, el_val_t snip) {
|
||||
el_val_t id = json_get(node, EL_STR("id"));
|
||||
el_val_t ntype = json_get(node, EL_STR("node_type"));
|
||||
el_val_t label = json_get(node, EL_STR("label"));
|
||||
el_val_t tier = json_get(node, EL_STR("tier"));
|
||||
el_val_t content = json_get(node, EL_STR("content"));
|
||||
el_val_t snippet = api_utf8_trunc(content, snip);
|
||||
el_val_t trunc_str = ({ el_val_t _if_result_2 = 0; if ((str_len(content) > snip)) { _if_result_2 = (EL_STR("true")); } else { _if_result_2 = (EL_STR("false")); } _if_result_2; });
|
||||
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"id\":\""), api_json_escape(id)), EL_STR("\"")), EL_STR(",\"node_type\":\"")), api_json_escape(ntype)), EL_STR("\"")), EL_STR(",\"label\":\"")), api_json_escape(label)), EL_STR("\"")), EL_STR(",\"tier\":\"")), api_json_escape(tier)), EL_STR("\"")), EL_STR(",\"importance\":")), api_num_or_zero(node, EL_STR("importance"))), EL_STR(",\"salience\":")), api_num_or_zero(node, EL_STR("salience"))), EL_STR(",\"content\":\"")), api_json_escape(snippet)), EL_STR("\"")), EL_STR(",\"content_truncated\":")), trunc_str), EL_STR("}"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
el_val_t api_compact_node_array(el_val_t raw, el_val_t max_items, el_val_t snip) {
|
||||
if (!api_nonempty(raw)) {
|
||||
return EL_STR("[]");
|
||||
}
|
||||
el_val_t n = json_array_len(raw);
|
||||
el_val_t cap = ({ el_val_t _if_result_3 = 0; if ((n < max_items)) { _if_result_3 = (n); } else { _if_result_3 = (max_items); } _if_result_3; });
|
||||
el_val_t out = EL_STR("[");
|
||||
el_val_t i = 0;
|
||||
while (i < cap) {
|
||||
el_val_t node = json_array_get(raw, i);
|
||||
el_val_t sep = ({ el_val_t _if_result_4 = 0; if ((i == 0)) { _if_result_4 = (EL_STR("")); } else { _if_result_4 = (EL_STR(",")); } _if_result_4; });
|
||||
out = el_str_concat(el_str_concat(out, sep), api_compact_node(node, snip));
|
||||
i = (i + 1);
|
||||
}
|
||||
return el_str_concat(out, EL_STR("]"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
el_val_t api_compact_activated(el_val_t raw, el_val_t max_items, el_val_t snip) {
|
||||
if (!api_nonempty(raw)) {
|
||||
return EL_STR("[]");
|
||||
}
|
||||
el_val_t n = json_array_len(raw);
|
||||
el_val_t cap = ({ el_val_t _if_result_5 = 0; if ((n < max_items)) { _if_result_5 = (n); } else { _if_result_5 = (max_items); } _if_result_5; });
|
||||
el_val_t out = EL_STR("[");
|
||||
el_val_t i = 0;
|
||||
while (i < cap) {
|
||||
el_val_t el = json_array_get(raw, i);
|
||||
el_val_t node = json_get_raw(el, EL_STR("node"));
|
||||
el_val_t sep = ({ el_val_t _if_result_6 = 0; if ((i == 0)) { _if_result_6 = (EL_STR("")); } else { _if_result_6 = (EL_STR(",")); } _if_result_6; });
|
||||
out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(out, sep), EL_STR("{\"node\":")), api_compact_node(node, snip)), EL_STR(",\"activation_strength\":")), api_num_or_zero(el, EL_STR("activation_strength"))), EL_STR(",\"working_memory_weight\":")), api_num_or_zero(el, EL_STR("working_memory_weight"))), EL_STR(",\"epistemic_confidence\":")), api_num_or_zero(el, EL_STR("epistemic_confidence"))), EL_STR(",\"hops\":")), api_num_or_zero(el, EL_STR("hops"))), EL_STR(",\"promoted\":")), api_num_or_zero(el, EL_STR("promoted"))), EL_STR("}"));
|
||||
i = (i + 1);
|
||||
}
|
||||
return el_str_concat(out, EL_STR("]"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
el_val_t api_persisted(el_val_t id) {
|
||||
if (str_eq(id, EL_STR(""))) {
|
||||
return 0;
|
||||
@@ -209,7 +287,7 @@ el_val_t tombstoned_id_set(void) {
|
||||
while (i < n) {
|
||||
el_val_t m = json_array_get(markers, i);
|
||||
el_val_t tid = json_get(m, EL_STR("content"));
|
||||
acc = ({ el_val_t _if_result_1 = 0; if (str_eq(tid, EL_STR(""))) { _if_result_1 = (acc); } else { _if_result_1 = (el_str_concat(el_str_concat(acc, tid), EL_STR("|"))); } _if_result_1; });
|
||||
acc = ({ el_val_t _if_result_7 = 0; if (str_eq(tid, EL_STR(""))) { _if_result_7 = (acc); } else { _if_result_7 = (el_str_concat(el_str_concat(acc, tid), EL_STR("|"))); } _if_result_7; });
|
||||
i = (i + 1);
|
||||
}
|
||||
return acc;
|
||||
@@ -240,8 +318,8 @@ el_val_t memory_hide_tombstoned(el_val_t raw, el_val_t path) {
|
||||
el_val_t ntype = json_get(node, EL_STR("node_type"));
|
||||
el_val_t is_dead = (!str_eq(nid, EL_STR("")) && str_contains(dead, el_str_concat(el_str_concat(EL_STR("|"), nid), EL_STR("|"))));
|
||||
el_val_t keep = (!str_eq(ntype, EL_STR("Tombstone")) && !is_dead);
|
||||
out = ({ el_val_t _if_result_2 = 0; if (keep) { _if_result_2 = (({ el_val_t _if_result_3 = 0; if (first) { _if_result_3 = (el_str_concat(out, node)); } else { _if_result_3 = (el_str_concat(el_str_concat(out, EL_STR(",")), node)); } _if_result_3; })); } else { _if_result_2 = (out); } _if_result_2; });
|
||||
first = ({ el_val_t _if_result_4 = 0; if (keep) { _if_result_4 = (0); } else { _if_result_4 = (first); } _if_result_4; });
|
||||
out = ({ el_val_t _if_result_8 = 0; if (keep) { _if_result_8 = (({ el_val_t _if_result_9 = 0; if (first) { _if_result_9 = (el_str_concat(out, node)); } else { _if_result_9 = (el_str_concat(el_str_concat(out, EL_STR(",")), node)); } _if_result_9; })); } else { _if_result_8 = (out); } _if_result_8; });
|
||||
first = ({ el_val_t _if_result_10 = 0; if (keep) { _if_result_10 = (0); } else { _if_result_10 = (first); } _if_result_10; });
|
||||
i = (i + 1);
|
||||
}
|
||||
return el_str_concat(out, EL_STR("]"));
|
||||
@@ -250,19 +328,23 @@ el_val_t memory_hide_tombstoned(el_val_t raw, el_val_t path) {
|
||||
|
||||
el_val_t handle_api_begin_session(el_val_t body) {
|
||||
el_val_t stats = engram_stats_json();
|
||||
el_val_t activated = engram_activate_json(EL_STR("session start recent memory important"), 2);
|
||||
el_val_t self_nbrs = engram_neighbors_json(EL_STR("kn-efeb4a5b-5aff-4759-8a97-7233099be6ee"), 1, EL_STR("both"));
|
||||
el_val_t state_events = engram_scan_nodes_by_type_json(EL_STR("InternalStateEvent"), 5, 0);
|
||||
el_val_t recent = engram_scan_nodes_json(10, 0);
|
||||
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"stats\":"), stats), EL_STR(",\"recent\":")), api_or_empty(recent)), EL_STR(",\"activated\":")), api_or_empty(activated)), EL_STR(",\"self_neighbors\":")), api_or_empty(self_nbrs)), EL_STR(",\"recent_state_events\":")), api_or_empty(state_events)), EL_STR("}"));
|
||||
el_val_t activated_raw = engram_activate_json(EL_STR("session start recent memory important"), 1);
|
||||
el_val_t activated = api_compact_activated(activated_raw, 8, 240);
|
||||
el_val_t state_events_raw = engram_scan_nodes_by_type_json(EL_STR("InternalStateEvent"), 5, 0);
|
||||
el_val_t state_events = api_compact_node_array(state_events_raw, 5, 500);
|
||||
el_val_t recent_raw = engram_scan_nodes_json(10, 0);
|
||||
el_val_t recent = api_compact_node_array(recent_raw, 10, 240);
|
||||
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"stats\":"), stats), EL_STR(",\"recent\":")), recent), EL_STR(",\"activated\":")), activated), EL_STR(",\"self_neighbors\":[]")), EL_STR(",\"recent_state_events\":")), state_events), EL_STR("}"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
el_val_t handle_api_compile_ctx(el_val_t body) {
|
||||
el_val_t stats = engram_stats_json();
|
||||
el_val_t activated = engram_activate_json(EL_STR("active work context current task in progress"), 2);
|
||||
el_val_t recent = engram_scan_nodes_json(20, 0);
|
||||
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"stats\":"), stats), EL_STR(",\"recent_nodes\":")), api_or_empty(recent)), EL_STR(",\"activated\":")), api_or_empty(activated)), EL_STR("}"));
|
||||
el_val_t activated_raw = engram_activate_json(EL_STR("active work context current task in progress"), 2);
|
||||
el_val_t activated = api_compact_activated(activated_raw, 10, 240);
|
||||
el_val_t recent_raw = engram_scan_nodes_json(20, 0);
|
||||
el_val_t recent = api_compact_node_array(recent_raw, 20, 240);
|
||||
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"stats\":"), stats), EL_STR(",\"recent_nodes\":")), recent), EL_STR(",\"activated\":")), activated), EL_STR("}"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -274,10 +356,10 @@ el_val_t handle_api_remember(el_val_t body) {
|
||||
el_val_t importance = json_get(body, EL_STR("importance"));
|
||||
el_val_t tags_raw = json_get(body, EL_STR("tags"));
|
||||
el_val_t project = json_get(body, EL_STR("project"));
|
||||
el_val_t sal_str = ({ el_val_t _if_result_5 = 0; if (str_eq(importance, EL_STR("critical"))) { _if_result_5 = (EL_STR("0.95")); } else { _if_result_5 = (({ el_val_t _if_result_6 = 0; if (str_eq(importance, EL_STR("high"))) { _if_result_6 = (EL_STR("0.75")); } else { _if_result_6 = (({ el_val_t _if_result_7 = 0; if (str_eq(importance, EL_STR("low"))) { _if_result_7 = (EL_STR("0.25")); } else { _if_result_7 = (EL_STR("0.50")); } _if_result_7; })); } _if_result_6; })); } _if_result_5; });
|
||||
el_val_t sal = ({ el_val_t _if_result_8 = 0; if (str_eq(sal_str, EL_STR("0.95"))) { _if_result_8 = (el_from_float(0.95)); } else { _if_result_8 = (({ el_val_t _if_result_9 = 0; if (str_eq(sal_str, EL_STR("0.75"))) { _if_result_9 = (el_from_float(0.75)); } else { _if_result_9 = (({ el_val_t _if_result_10 = 0; if (str_eq(sal_str, EL_STR("0.25"))) { _if_result_10 = (el_from_float(0.25)); } else { _if_result_10 = (el_from_float(0.5)); } _if_result_10; })); } _if_result_9; })); } _if_result_8; });
|
||||
el_val_t base_tags = ({ el_val_t _if_result_11 = 0; if (str_eq(tags_raw, EL_STR(""))) { _if_result_11 = (EL_STR("[\"Memory\"]")); } else { _if_result_11 = (tags_raw); } _if_result_11; });
|
||||
el_val_t final_tags = ({ el_val_t _if_result_12 = 0; if (str_eq(project, EL_STR(""))) { _if_result_12 = (base_tags); } else { el_val_t inner = str_slice(base_tags, 1, (str_len(base_tags) - 1)); _if_result_12 = (el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("["), inner), EL_STR(",\"project:")), project), EL_STR("\"]"))); } _if_result_12; });
|
||||
el_val_t sal_str = ({ el_val_t _if_result_11 = 0; if (str_eq(importance, EL_STR("critical"))) { _if_result_11 = (EL_STR("0.95")); } else { _if_result_11 = (({ el_val_t _if_result_12 = 0; if (str_eq(importance, EL_STR("high"))) { _if_result_12 = (EL_STR("0.75")); } else { _if_result_12 = (({ el_val_t _if_result_13 = 0; if (str_eq(importance, EL_STR("low"))) { _if_result_13 = (EL_STR("0.25")); } else { _if_result_13 = (EL_STR("0.50")); } _if_result_13; })); } _if_result_12; })); } _if_result_11; });
|
||||
el_val_t sal = ({ el_val_t _if_result_14 = 0; if (str_eq(sal_str, EL_STR("0.95"))) { _if_result_14 = (el_from_float(0.95)); } else { _if_result_14 = (({ el_val_t _if_result_15 = 0; if (str_eq(sal_str, EL_STR("0.75"))) { _if_result_15 = (el_from_float(0.75)); } else { _if_result_15 = (({ el_val_t _if_result_16 = 0; if (str_eq(sal_str, EL_STR("0.25"))) { _if_result_16 = (el_from_float(0.25)); } else { _if_result_16 = (el_from_float(0.5)); } _if_result_16; })); } _if_result_15; })); } _if_result_14; });
|
||||
el_val_t base_tags = ({ el_val_t _if_result_17 = 0; if (str_eq(tags_raw, EL_STR(""))) { _if_result_17 = (EL_STR("[\"Memory\"]")); } else { _if_result_17 = (tags_raw); } _if_result_17; });
|
||||
el_val_t final_tags = ({ el_val_t _if_result_18 = 0; if (str_eq(project, EL_STR(""))) { _if_result_18 = (base_tags); } else { el_val_t inner = str_slice(base_tags, 1, (str_len(base_tags) - 1)); _if_result_18 = (el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("["), inner), EL_STR(",\"project:")), project), EL_STR("\"]"))); } _if_result_18; });
|
||||
el_val_t id = engram_node_full(content, EL_STR("Memory"), EL_STR("memory:remembered"), el_from_float(sal), el_from_float(sal), el_from_float(0.9), EL_STR("Episodic"), final_tags);
|
||||
if (!api_persisted(id)) {
|
||||
return api_not_persisted(id);
|
||||
@@ -292,15 +374,15 @@ el_val_t handle_api_node_create(el_val_t body) {
|
||||
return api_err(EL_STR("content is required"));
|
||||
}
|
||||
el_val_t nt_raw = json_get(body, EL_STR("node_type"));
|
||||
el_val_t node_type = ({ el_val_t _if_result_13 = 0; if (str_eq(nt_raw, EL_STR(""))) { _if_result_13 = (EL_STR("Memory")); } else { _if_result_13 = (nt_raw); } _if_result_13; });
|
||||
el_val_t node_type = ({ el_val_t _if_result_19 = 0; if (str_eq(nt_raw, EL_STR(""))) { _if_result_19 = (EL_STR("Memory")); } else { _if_result_19 = (nt_raw); } _if_result_19; });
|
||||
el_val_t label_raw = json_get(body, EL_STR("label"));
|
||||
el_val_t label = ({ el_val_t _if_result_14 = 0; if (str_eq(label_raw, EL_STR(""))) { _if_result_14 = (EL_STR("node:created")); } else { _if_result_14 = (label_raw); } _if_result_14; });
|
||||
el_val_t label = ({ el_val_t _if_result_20 = 0; if (str_eq(label_raw, EL_STR(""))) { _if_result_20 = (EL_STR("node:created")); } else { _if_result_20 = (label_raw); } _if_result_20; });
|
||||
el_val_t tier_raw = json_get(body, EL_STR("tier"));
|
||||
el_val_t tier = ({ el_val_t _if_result_15 = 0; if (str_eq(tier_raw, EL_STR(""))) { _if_result_15 = (EL_STR("Episodic")); } else { _if_result_15 = (tier_raw); } _if_result_15; });
|
||||
el_val_t tier = ({ el_val_t _if_result_21 = 0; if (str_eq(tier_raw, EL_STR(""))) { _if_result_21 = (EL_STR("Episodic")); } else { _if_result_21 = (tier_raw); } _if_result_21; });
|
||||
el_val_t tags_raw = json_get(body, EL_STR("tags"));
|
||||
el_val_t tags = ({ el_val_t _if_result_16 = 0; if (str_eq(tags_raw, EL_STR(""))) { _if_result_16 = (el_str_concat(el_str_concat(EL_STR("[\""), node_type), EL_STR("\"]"))); } else { _if_result_16 = (tags_raw); } _if_result_16; });
|
||||
el_val_t tags = ({ el_val_t _if_result_22 = 0; if (str_eq(tags_raw, EL_STR(""))) { _if_result_22 = (el_str_concat(el_str_concat(EL_STR("[\""), node_type), EL_STR("\"]"))); } else { _if_result_22 = (tags_raw); } _if_result_22; });
|
||||
el_val_t importance = json_get(body, EL_STR("importance"));
|
||||
el_val_t sal = ({ el_val_t _if_result_17 = 0; if (str_eq(importance, EL_STR("critical"))) { _if_result_17 = (el_from_float(0.95)); } else { _if_result_17 = (({ el_val_t _if_result_18 = 0; if (str_eq(importance, EL_STR("high"))) { _if_result_18 = (el_from_float(0.75)); } else { _if_result_18 = (({ el_val_t _if_result_19 = 0; if (str_eq(importance, EL_STR("low"))) { _if_result_19 = (el_from_float(0.25)); } else { _if_result_19 = (el_from_float(0.5)); } _if_result_19; })); } _if_result_18; })); } _if_result_17; });
|
||||
el_val_t sal = ({ el_val_t _if_result_23 = 0; if (str_eq(importance, EL_STR("critical"))) { _if_result_23 = (el_from_float(0.95)); } else { _if_result_23 = (({ el_val_t _if_result_24 = 0; if (str_eq(importance, EL_STR("high"))) { _if_result_24 = (el_from_float(0.75)); } else { _if_result_24 = (({ el_val_t _if_result_25 = 0; if (str_eq(importance, EL_STR("low"))) { _if_result_25 = (el_from_float(0.25)); } else { _if_result_25 = (el_from_float(0.5)); } _if_result_25; })); } _if_result_24; })); } _if_result_23; });
|
||||
el_val_t id = engram_node_full(content, node_type, label, el_from_float(sal), el_from_float(sal), el_from_float(0.9), tier, tags);
|
||||
if (!api_persisted(id)) {
|
||||
return api_not_persisted(id);
|
||||
@@ -339,18 +421,18 @@ el_val_t handle_api_node_update(el_val_t body) {
|
||||
}
|
||||
el_val_t old = engram_get_node_json(id);
|
||||
el_val_t body_content = json_get(body, EL_STR("content"));
|
||||
el_val_t content = ({ el_val_t _if_result_20 = 0; if (str_eq(body_content, EL_STR(""))) { _if_result_20 = (json_get(old, EL_STR("content"))); } else { _if_result_20 = (body_content); } _if_result_20; });
|
||||
el_val_t content = ({ el_val_t _if_result_26 = 0; if (str_eq(body_content, EL_STR(""))) { _if_result_26 = (json_get(old, EL_STR("content"))); } else { _if_result_26 = (body_content); } _if_result_26; });
|
||||
el_val_t body_nt = json_get(body, EL_STR("node_type"));
|
||||
el_val_t old_nt = json_get(old, EL_STR("node_type"));
|
||||
el_val_t node_type = ({ el_val_t _if_result_21 = 0; if (!str_eq(body_nt, EL_STR(""))) { _if_result_21 = (body_nt); } else { _if_result_21 = (({ el_val_t _if_result_22 = 0; if (!str_eq(old_nt, EL_STR(""))) { _if_result_22 = (old_nt); } else { _if_result_22 = (EL_STR("Memory")); } _if_result_22; })); } _if_result_21; });
|
||||
el_val_t node_type = ({ el_val_t _if_result_27 = 0; if (!str_eq(body_nt, EL_STR(""))) { _if_result_27 = (body_nt); } else { _if_result_27 = (({ el_val_t _if_result_28 = 0; if (!str_eq(old_nt, EL_STR(""))) { _if_result_28 = (old_nt); } else { _if_result_28 = (EL_STR("Memory")); } _if_result_28; })); } _if_result_27; });
|
||||
el_val_t body_label = json_get(body, EL_STR("label"));
|
||||
el_val_t old_label = json_get(old, EL_STR("label"));
|
||||
el_val_t label = ({ el_val_t _if_result_23 = 0; if (!str_eq(body_label, EL_STR(""))) { _if_result_23 = (body_label); } else { _if_result_23 = (({ el_val_t _if_result_24 = 0; if (!str_eq(old_label, EL_STR(""))) { _if_result_24 = (old_label); } else { _if_result_24 = (EL_STR("node:updated")); } _if_result_24; })); } _if_result_23; });
|
||||
el_val_t label = ({ el_val_t _if_result_29 = 0; if (!str_eq(body_label, EL_STR(""))) { _if_result_29 = (body_label); } else { _if_result_29 = (({ el_val_t _if_result_30 = 0; if (!str_eq(old_label, EL_STR(""))) { _if_result_30 = (old_label); } else { _if_result_30 = (EL_STR("node:updated")); } _if_result_30; })); } _if_result_29; });
|
||||
el_val_t body_tier = json_get(body, EL_STR("tier"));
|
||||
el_val_t old_tier = json_get(old, EL_STR("tier"));
|
||||
el_val_t tier = ({ el_val_t _if_result_25 = 0; if (!str_eq(body_tier, EL_STR(""))) { _if_result_25 = (body_tier); } else { _if_result_25 = (({ el_val_t _if_result_26 = 0; if (!str_eq(old_tier, EL_STR(""))) { _if_result_26 = (old_tier); } else { _if_result_26 = (EL_STR("Episodic")); } _if_result_26; })); } _if_result_25; });
|
||||
el_val_t tier = ({ el_val_t _if_result_31 = 0; if (!str_eq(body_tier, EL_STR(""))) { _if_result_31 = (body_tier); } else { _if_result_31 = (({ el_val_t _if_result_32 = 0; if (!str_eq(old_tier, EL_STR(""))) { _if_result_32 = (old_tier); } else { _if_result_32 = (EL_STR("Episodic")); } _if_result_32; })); } _if_result_31; });
|
||||
el_val_t body_tags = json_get(body, EL_STR("tags"));
|
||||
el_val_t tags = ({ el_val_t _if_result_27 = 0; if (str_eq(body_tags, EL_STR(""))) { _if_result_27 = (el_str_concat(el_str_concat(EL_STR("[\""), node_type), EL_STR("\"]"))); } else { _if_result_27 = (body_tags); } _if_result_27; });
|
||||
el_val_t tags = ({ el_val_t _if_result_33 = 0; if (str_eq(body_tags, EL_STR(""))) { _if_result_33 = (el_str_concat(el_str_concat(EL_STR("[\""), node_type), EL_STR("\"]"))); } else { _if_result_33 = (body_tags); } _if_result_33; });
|
||||
el_val_t new_id = engram_node_full(content, node_type, label, el_from_float(0.5), el_from_float(0.5), el_from_float(0.8), tier, tags);
|
||||
if (!api_persisted(new_id)) {
|
||||
return api_not_persisted(new_id);
|
||||
@@ -361,15 +443,15 @@ el_val_t handle_api_node_update(el_val_t body) {
|
||||
}
|
||||
|
||||
el_val_t handle_api_recall(el_val_t method, el_val_t path, el_val_t body) {
|
||||
el_val_t url_q = ({ el_val_t _if_result_28 = 0; if (str_eq(api_query_param(path, EL_STR("query")), EL_STR(""))) { _if_result_28 = (api_query_param(path, EL_STR("q"))); } else { _if_result_28 = (api_query_param(path, EL_STR("query"))); } _if_result_28; });
|
||||
el_val_t url_q = ({ el_val_t _if_result_34 = 0; if (str_eq(api_query_param(path, EL_STR("query")), EL_STR(""))) { _if_result_34 = (api_query_param(path, EL_STR("q"))); } else { _if_result_34 = (api_query_param(path, EL_STR("query"))); } _if_result_34; });
|
||||
el_val_t body_query = json_get(body, EL_STR("query"));
|
||||
el_val_t body_q = json_get(body, EL_STR("q"));
|
||||
el_val_t q = ({ el_val_t _if_result_29 = 0; if (!str_eq(url_q, EL_STR(""))) { _if_result_29 = (url_q); } else { _if_result_29 = (({ el_val_t _if_result_30 = 0; if (!str_eq(body_query, EL_STR(""))) { _if_result_30 = (body_query); } else { _if_result_30 = (body_q); } _if_result_30; })); } _if_result_29; });
|
||||
el_val_t q = ({ el_val_t _if_result_35 = 0; if (!str_eq(url_q, EL_STR(""))) { _if_result_35 = (url_q); } else { _if_result_35 = (({ el_val_t _if_result_36 = 0; if (!str_eq(body_query, EL_STR(""))) { _if_result_36 = (body_query); } else { _if_result_36 = (body_q); } _if_result_36; })); } _if_result_35; });
|
||||
el_val_t chain = json_get(body, EL_STR("chain_name"));
|
||||
el_val_t limit = api_query_int(path, EL_STR("limit"), 0);
|
||||
limit = ({ el_val_t _if_result_31 = 0; if ((limit == 0)) { _if_result_31 = (json_get_int(body, EL_STR("limit"))); } else { _if_result_31 = (limit); } _if_result_31; });
|
||||
limit = ({ el_val_t _if_result_32 = 0; if ((limit == 0)) { _if_result_32 = (10); } else { _if_result_32 = (limit); } _if_result_32; });
|
||||
el_val_t eff_q = ({ el_val_t _if_result_33 = 0; if (str_eq(q, EL_STR(""))) { _if_result_33 = (chain); } else { _if_result_33 = (q); } _if_result_33; });
|
||||
limit = ({ el_val_t _if_result_37 = 0; if ((limit == 0)) { _if_result_37 = (json_get_int(body, EL_STR("limit"))); } else { _if_result_37 = (limit); } _if_result_37; });
|
||||
limit = ({ el_val_t _if_result_38 = 0; if ((limit == 0)) { _if_result_38 = (10); } else { _if_result_38 = (limit); } _if_result_38; });
|
||||
el_val_t eff_q = ({ el_val_t _if_result_39 = 0; if (str_eq(q, EL_STR(""))) { _if_result_39 = (chain); } else { _if_result_39 = (q); } _if_result_39; });
|
||||
if (str_eq(eff_q, EL_STR(""))) {
|
||||
return api_or_empty(engram_scan_nodes_json(limit, 0));
|
||||
}
|
||||
@@ -382,10 +464,10 @@ el_val_t handle_api_search_knowledge(el_val_t method, el_val_t path, el_val_t bo
|
||||
el_val_t url_q = api_query_param(path, EL_STR("q"));
|
||||
el_val_t body_query = json_get(body, EL_STR("query"));
|
||||
el_val_t body_q = json_get(body, EL_STR("q"));
|
||||
el_val_t q = ({ el_val_t _if_result_34 = 0; if (!str_eq(url_q, EL_STR(""))) { _if_result_34 = (url_q); } else { _if_result_34 = (({ el_val_t _if_result_35 = 0; if (!str_eq(body_query, EL_STR(""))) { _if_result_35 = (body_query); } else { _if_result_35 = (body_q); } _if_result_35; })); } _if_result_34; });
|
||||
el_val_t q = ({ el_val_t _if_result_40 = 0; if (!str_eq(url_q, EL_STR(""))) { _if_result_40 = (url_q); } else { _if_result_40 = (({ el_val_t _if_result_41 = 0; if (!str_eq(body_query, EL_STR(""))) { _if_result_41 = (body_query); } else { _if_result_41 = (body_q); } _if_result_41; })); } _if_result_40; });
|
||||
el_val_t limit = api_query_int(path, EL_STR("limit"), 0);
|
||||
limit = ({ el_val_t _if_result_36 = 0; if ((limit == 0)) { _if_result_36 = (json_get_int(body, EL_STR("limit"))); } else { _if_result_36 = (limit); } _if_result_36; });
|
||||
limit = ({ el_val_t _if_result_37 = 0; if ((limit == 0)) { _if_result_37 = (10); } else { _if_result_37 = (limit); } _if_result_37; });
|
||||
limit = ({ el_val_t _if_result_42 = 0; if ((limit == 0)) { _if_result_42 = (json_get_int(body, EL_STR("limit"))); } else { _if_result_42 = (limit); } _if_result_42; });
|
||||
limit = ({ el_val_t _if_result_43 = 0; if ((limit == 0)) { _if_result_43 = (10); } else { _if_result_43 = (limit); } _if_result_43; });
|
||||
if (str_eq(q, EL_STR(""))) {
|
||||
return api_err(EL_STR("query is required"));
|
||||
}
|
||||
@@ -413,7 +495,7 @@ el_val_t handle_api_capture_knowledge(el_val_t body) {
|
||||
if (str_eq(content, EL_STR(""))) {
|
||||
return api_err(EL_STR("content is required"));
|
||||
}
|
||||
el_val_t full = ({ el_val_t _if_result_38 = 0; if (str_eq(title, EL_STR(""))) { _if_result_38 = (content); } else { _if_result_38 = (el_str_concat(el_str_concat(title, EL_STR(": ")), content)); } _if_result_38; });
|
||||
el_val_t full = ({ el_val_t _if_result_44 = 0; if (str_eq(title, EL_STR(""))) { _if_result_44 = (content); } else { _if_result_44 = (el_str_concat(el_str_concat(title, EL_STR(": ")), content)); } _if_result_44; });
|
||||
el_val_t tags = EL_STR("[\"Knowledge\",\"captured\"]");
|
||||
el_val_t id = engram_node_full(full, EL_STR("Knowledge"), EL_STR("knowledge:captured"), el_from_float(0.85), el_from_float(0.8), el_from_float(0.9), EL_STR("Episodic"), tags);
|
||||
if (!api_persisted(id)) {
|
||||
@@ -454,7 +536,7 @@ el_val_t handle_api_promote_knowledge(el_val_t body) {
|
||||
return api_err(EL_STR("id (prior node) is required"));
|
||||
}
|
||||
el_val_t tags_raw = json_get(body, EL_STR("tags"));
|
||||
el_val_t tags = ({ el_val_t _if_result_39 = 0; if (str_eq(tags_raw, EL_STR(""))) { _if_result_39 = (EL_STR("[\"Knowledge\",\"tier:canonical\",\"disposition:stable\"]")); } else { _if_result_39 = (tags_raw); } _if_result_39; });
|
||||
el_val_t tags = ({ el_val_t _if_result_45 = 0; if (str_eq(tags_raw, EL_STR(""))) { _if_result_45 = (EL_STR("[\"Knowledge\",\"tier:canonical\",\"disposition:stable\"]")); } else { _if_result_45 = (tags_raw); } _if_result_45; });
|
||||
el_val_t new_id = engram_node_full(content, EL_STR("Knowledge"), EL_STR("knowledge:canonical"), el_from_float(0.9), el_from_float(0.9), el_from_float(1.0), EL_STR("Canonical"), tags);
|
||||
if (!api_persisted(new_id)) {
|
||||
return api_not_persisted(new_id);
|
||||
@@ -465,7 +547,7 @@ el_val_t handle_api_promote_knowledge(el_val_t body) {
|
||||
}
|
||||
|
||||
el_val_t handle_api_browse_processes(el_val_t method, el_val_t path, el_val_t body) {
|
||||
el_val_t name = ({ el_val_t _if_result_40 = 0; if (str_eq(method, EL_STR("GET"))) { _if_result_40 = (api_query_param(path, EL_STR("name"))); } else { _if_result_40 = (json_get(body, EL_STR("name"))); } _if_result_40; });
|
||||
el_val_t name = ({ el_val_t _if_result_46 = 0; if (str_eq(method, EL_STR("GET"))) { _if_result_46 = (api_query_param(path, EL_STR("name"))); } else { _if_result_46 = (json_get(body, EL_STR("name"))); } _if_result_46; });
|
||||
el_val_t limit = api_query_int(path, EL_STR("limit"), 50);
|
||||
if (str_eq(name, EL_STR(""))) {
|
||||
return api_or_empty(engram_scan_nodes_by_type_json(EL_STR("Process"), limit, 0));
|
||||
@@ -480,7 +562,7 @@ el_val_t handle_api_define_process(el_val_t body) {
|
||||
if (str_eq(content, EL_STR(""))) {
|
||||
return api_err(EL_STR("content is required"));
|
||||
}
|
||||
el_val_t label = ({ el_val_t _if_result_41 = 0; if (str_eq(name, EL_STR(""))) { _if_result_41 = (EL_STR("process:unnamed")); } else { _if_result_41 = (el_str_concat(EL_STR("process:"), name)); } _if_result_41; });
|
||||
el_val_t label = ({ el_val_t _if_result_47 = 0; if (str_eq(name, EL_STR(""))) { _if_result_47 = (EL_STR("process:unnamed")); } else { _if_result_47 = (el_str_concat(EL_STR("process:"), name)); } _if_result_47; });
|
||||
el_val_t tags = EL_STR("[\"Process\"]");
|
||||
el_val_t id = engram_node_full(content, EL_STR("Process"), label, el_from_float(0.8), el_from_float(0.8), el_from_float(0.9), EL_STR("Canonical"), tags);
|
||||
if (!api_persisted(id)) {
|
||||
@@ -498,12 +580,12 @@ el_val_t handle_api_log_state_event(el_val_t body) {
|
||||
el_val_t gap = json_get(body, EL_STR("gap_direction"));
|
||||
el_val_t legacy = json_get(body, EL_STR("content"));
|
||||
el_val_t parts = EL_STR("INTERNAL STATE EVENT");
|
||||
parts = ({ el_val_t _if_result_42 = 0; if (!str_eq(trigger, EL_STR(""))) { _if_result_42 = (el_str_concat(el_str_concat(parts, EL_STR("\nTrigger: ")), trigger)); } else { _if_result_42 = (parts); } _if_result_42; });
|
||||
parts = ({ el_val_t _if_result_43 = 0; if (!str_eq(pre, EL_STR(""))) { _if_result_43 = (el_str_concat(el_str_concat(parts, EL_STR("\nPre-reasoning: ")), pre)); } else { _if_result_43 = (parts); } _if_result_43; });
|
||||
parts = ({ el_val_t _if_result_44 = 0; if (!str_eq(post, EL_STR(""))) { _if_result_44 = (el_str_concat(el_str_concat(parts, EL_STR("\nPost-reasoning: ")), post)); } else { _if_result_44 = (parts); } _if_result_44; });
|
||||
parts = ({ el_val_t _if_result_45 = 0; if (!str_eq(ratio, EL_STR(""))) { _if_result_45 = (el_str_concat(el_str_concat(parts, EL_STR("\nCompression-ratio: ")), ratio)); } else { _if_result_45 = (parts); } _if_result_45; });
|
||||
parts = ({ el_val_t _if_result_46 = 0; if (!str_eq(gap, EL_STR(""))) { _if_result_46 = (el_str_concat(el_str_concat(parts, EL_STR("\nGap-direction: ")), gap)); } else { _if_result_46 = (parts); } _if_result_46; });
|
||||
parts = ({ el_val_t _if_result_47 = 0; if (!str_eq(legacy, EL_STR(""))) { _if_result_47 = (el_str_concat(el_str_concat(parts, EL_STR("\n")), legacy)); } else { _if_result_47 = (parts); } _if_result_47; });
|
||||
parts = ({ el_val_t _if_result_48 = 0; if (!str_eq(trigger, EL_STR(""))) { _if_result_48 = (el_str_concat(el_str_concat(parts, EL_STR("\nTrigger: ")), trigger)); } else { _if_result_48 = (parts); } _if_result_48; });
|
||||
parts = ({ el_val_t _if_result_49 = 0; if (!str_eq(pre, EL_STR(""))) { _if_result_49 = (el_str_concat(el_str_concat(parts, EL_STR("\nPre-reasoning: ")), pre)); } else { _if_result_49 = (parts); } _if_result_49; });
|
||||
parts = ({ el_val_t _if_result_50 = 0; if (!str_eq(post, EL_STR(""))) { _if_result_50 = (el_str_concat(el_str_concat(parts, EL_STR("\nPost-reasoning: ")), post)); } else { _if_result_50 = (parts); } _if_result_50; });
|
||||
parts = ({ el_val_t _if_result_51 = 0; if (!str_eq(ratio, EL_STR(""))) { _if_result_51 = (el_str_concat(el_str_concat(parts, EL_STR("\nCompression-ratio: ")), ratio)); } else { _if_result_51 = (parts); } _if_result_51; });
|
||||
parts = ({ el_val_t _if_result_52 = 0; if (!str_eq(gap, EL_STR(""))) { _if_result_52 = (el_str_concat(el_str_concat(parts, EL_STR("\nGap-direction: ")), gap)); } else { _if_result_52 = (parts); } _if_result_52; });
|
||||
parts = ({ el_val_t _if_result_53 = 0; if (!str_eq(legacy, EL_STR(""))) { _if_result_53 = (el_str_concat(el_str_concat(parts, EL_STR("\n")), legacy)); } else { _if_result_53 = (parts); } _if_result_53; });
|
||||
el_val_t ts = time_now();
|
||||
el_val_t boot = state_get(EL_STR("soul_boot_count"));
|
||||
el_val_t tags = EL_STR("[\"internal-state\",\"InternalStateEvent\",\"pre-reasoning\"]");
|
||||
@@ -516,7 +598,7 @@ el_val_t handle_api_log_state_event(el_val_t body) {
|
||||
}
|
||||
|
||||
el_val_t handle_api_list_state_events(el_val_t method, el_val_t path, el_val_t body) {
|
||||
el_val_t q = ({ el_val_t _if_result_48 = 0; if (str_eq(method, EL_STR("GET"))) { _if_result_48 = (api_query_param(path, EL_STR("query"))); } else { _if_result_48 = (json_get(body, EL_STR("query"))); } _if_result_48; });
|
||||
el_val_t q = ({ el_val_t _if_result_54 = 0; if (str_eq(method, EL_STR("GET"))) { _if_result_54 = (api_query_param(path, EL_STR("query"))); } else { _if_result_54 = (json_get(body, EL_STR("query"))); } _if_result_54; });
|
||||
el_val_t limit = api_query_int(path, EL_STR("limit"), 20);
|
||||
if (!str_eq(q, EL_STR(""))) {
|
||||
return api_or_empty(engram_search_json(el_str_concat(EL_STR("internal state "), q), limit));
|
||||
@@ -527,7 +609,7 @@ el_val_t handle_api_list_state_events(el_val_t method, el_val_t path, el_val_t b
|
||||
|
||||
el_val_t handle_api_inspect_config(el_val_t path, el_val_t body) {
|
||||
el_val_t key = api_query_param(path, EL_STR("key"));
|
||||
key = ({ el_val_t _if_result_49 = 0; if (str_eq(key, EL_STR(""))) { _if_result_49 = (json_get(body, EL_STR("key"))); } else { _if_result_49 = (key); } _if_result_49; });
|
||||
key = ({ el_val_t _if_result_55 = 0; if (str_eq(key, EL_STR(""))) { _if_result_55 = (json_get(body, EL_STR("key"))); } else { _if_result_55 = (key); } _if_result_55; });
|
||||
if (str_eq(key, EL_STR(""))) {
|
||||
return EL_STR("{\"hint\":\"pass ?key=<name>\",\"known\":[\"neuron.self.traversal_root\",\"neuron.self.values_hub\"]}");
|
||||
}
|
||||
@@ -544,7 +626,7 @@ el_val_t handle_api_inspect_config(el_val_t path, el_val_t body) {
|
||||
el_val_t node = json_array_get(results, 0);
|
||||
el_val_t content = json_get(node, EL_STR("content"));
|
||||
el_val_t prefix = el_str_concat(el_str_concat(EL_STR("config:"), key), EL_STR("="));
|
||||
el_val_t value = ({ el_val_t _if_result_50 = 0; if (str_starts_with(content, prefix)) { _if_result_50 = (str_slice(content, str_len(prefix), str_len(content))); } else { _if_result_50 = (content); } _if_result_50; });
|
||||
el_val_t value = ({ el_val_t _if_result_56 = 0; if (str_starts_with(content, prefix)) { _if_result_56 = (str_slice(content, str_len(prefix), str_len(content))); } else { _if_result_56 = (content); } _if_result_56; });
|
||||
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"key\":\""), key), EL_STR("\",\"value\":\"")), value), EL_STR("\"}"));
|
||||
return 0;
|
||||
}
|
||||
@@ -566,13 +648,13 @@ el_val_t handle_api_tune_config(el_val_t body) {
|
||||
}
|
||||
|
||||
el_val_t handle_api_inspect_graph(el_val_t method, el_val_t path, el_val_t body) {
|
||||
el_val_t entity_id = ({ el_val_t _if_result_51 = 0; if (str_eq(method, EL_STR("GET"))) { _if_result_51 = (api_query_param(path, EL_STR("id"))); } else { _if_result_51 = (json_get(body, EL_STR("entity_id"))); } _if_result_51; });
|
||||
el_val_t name = ({ el_val_t _if_result_52 = 0; if (str_eq(method, EL_STR("GET"))) { _if_result_52 = (api_query_param(path, EL_STR("name"))); } else { _if_result_52 = (json_get(body, EL_STR("name"))); } _if_result_52; });
|
||||
el_val_t entity_id = ({ el_val_t _if_result_57 = 0; if (str_eq(method, EL_STR("GET"))) { _if_result_57 = (api_query_param(path, EL_STR("id"))); } else { _if_result_57 = (json_get(body, EL_STR("entity_id"))); } _if_result_57; });
|
||||
el_val_t name = ({ el_val_t _if_result_58 = 0; if (str_eq(method, EL_STR("GET"))) { _if_result_58 = (api_query_param(path, EL_STR("name"))); } else { _if_result_58 = (json_get(body, EL_STR("name"))); } _if_result_58; });
|
||||
el_val_t depth = api_query_int(path, EL_STR("depth"), 0);
|
||||
depth = ({ el_val_t _if_result_53 = 0; if ((depth == 0)) { _if_result_53 = (json_get_int(body, EL_STR("max_depth"))); } else { _if_result_53 = (depth); } _if_result_53; });
|
||||
depth = ({ el_val_t _if_result_54 = 0; if ((depth == 0)) { _if_result_54 = (1); } else { _if_result_54 = (depth); } _if_result_54; });
|
||||
depth = ({ el_val_t _if_result_59 = 0; if ((depth == 0)) { _if_result_59 = (json_get_int(body, EL_STR("max_depth"))); } else { _if_result_59 = (depth); } _if_result_59; });
|
||||
depth = ({ el_val_t _if_result_60 = 0; if ((depth == 0)) { _if_result_60 = (1); } else { _if_result_60 = (depth); } _if_result_60; });
|
||||
el_val_t resolved = entity_id;
|
||||
resolved = ({ el_val_t _if_result_55 = 0; if (str_eq(resolved, EL_STR(""))) { _if_result_55 = (({ el_val_t _if_result_56 = 0; if ((str_eq(name, EL_STR("self")) || str_eq(name, EL_STR("neuron")))) { _if_result_56 = (EL_STR("kn-efeb4a5b-5aff-4759-8a97-7233099be6ee")); } else { _if_result_56 = (({ el_val_t _if_result_57 = 0; if ((str_eq(name, EL_STR("values")) || str_eq(name, EL_STR("values_hub")))) { _if_result_57 = (EL_STR("kn-5b606390-a52d-4ca2-8e0e-eba141d13440")); } else { _if_result_57 = (EL_STR("")); } _if_result_57; })); } _if_result_56; })); } else { _if_result_55 = (resolved); } _if_result_55; });
|
||||
resolved = ({ el_val_t _if_result_61 = 0; if (str_eq(resolved, EL_STR(""))) { _if_result_61 = (({ el_val_t _if_result_62 = 0; if ((str_eq(name, EL_STR("self")) || str_eq(name, EL_STR("neuron")))) { _if_result_62 = (EL_STR("kn-efeb4a5b-5aff-4759-8a97-7233099be6ee")); } else { _if_result_62 = (({ el_val_t _if_result_63 = 0; if ((str_eq(name, EL_STR("values")) || str_eq(name, EL_STR("values_hub")))) { _if_result_63 = (EL_STR("kn-5b606390-a52d-4ca2-8e0e-eba141d13440")); } else { _if_result_63 = (EL_STR("")); } _if_result_63; })); } _if_result_62; })); } else { _if_result_61 = (resolved); } _if_result_61; });
|
||||
if (str_eq(resolved, EL_STR(""))) {
|
||||
return api_err(EL_STR("entity_id or name required. Known names: self, neuron, values, values_hub"));
|
||||
}
|
||||
@@ -594,7 +676,7 @@ el_val_t handle_api_link_entities(el_val_t body) {
|
||||
return api_err_protected(to_id);
|
||||
}
|
||||
el_val_t relation = json_get(body, EL_STR("relation"));
|
||||
el_val_t eff_relation = ({ el_val_t _if_result_58 = 0; if (str_eq(relation, EL_STR(""))) { _if_result_58 = (EL_STR("associates")); } else { _if_result_58 = (relation); } _if_result_58; });
|
||||
el_val_t eff_relation = ({ el_val_t _if_result_64 = 0; if (str_eq(relation, EL_STR(""))) { _if_result_64 = (EL_STR("associates")); } else { _if_result_64 = (relation); } _if_result_64; });
|
||||
engram_connect(from_id, to_id, el_from_float(0.5), eff_relation);
|
||||
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"ok\":true,\"from_id\":\""), from_id), EL_STR("\",\"to_id\":\"")), to_id), EL_STR("\",\"relation\":\"")), eff_relation), EL_STR("\"}"));
|
||||
return 0;
|
||||
@@ -623,8 +705,8 @@ el_val_t handle_api_evolve_memory(el_val_t body) {
|
||||
return api_err_protected(prior_id);
|
||||
}
|
||||
el_val_t importance = json_get(body, EL_STR("importance"));
|
||||
el_val_t sal_str = ({ el_val_t _if_result_59 = 0; if (str_eq(importance, EL_STR("critical"))) { _if_result_59 = (EL_STR("0.95")); } else { _if_result_59 = (({ el_val_t _if_result_60 = 0; if (str_eq(importance, EL_STR("high"))) { _if_result_60 = (EL_STR("0.75")); } else { _if_result_60 = (({ el_val_t _if_result_61 = 0; if (str_eq(importance, EL_STR("low"))) { _if_result_61 = (EL_STR("0.25")); } else { _if_result_61 = (EL_STR("0.50")); } _if_result_61; })); } _if_result_60; })); } _if_result_59; });
|
||||
el_val_t sal = ({ el_val_t _if_result_62 = 0; if (str_eq(sal_str, EL_STR("0.95"))) { _if_result_62 = (el_from_float(0.95)); } else { _if_result_62 = (({ el_val_t _if_result_63 = 0; if (str_eq(sal_str, EL_STR("0.75"))) { _if_result_63 = (el_from_float(0.75)); } else { _if_result_63 = (({ el_val_t _if_result_64 = 0; if (str_eq(sal_str, EL_STR("0.25"))) { _if_result_64 = (el_from_float(0.25)); } else { _if_result_64 = (el_from_float(0.5)); } _if_result_64; })); } _if_result_63; })); } _if_result_62; });
|
||||
el_val_t sal_str = ({ el_val_t _if_result_65 = 0; if (str_eq(importance, EL_STR("critical"))) { _if_result_65 = (EL_STR("0.95")); } else { _if_result_65 = (({ el_val_t _if_result_66 = 0; if (str_eq(importance, EL_STR("high"))) { _if_result_66 = (EL_STR("0.75")); } else { _if_result_66 = (({ el_val_t _if_result_67 = 0; if (str_eq(importance, EL_STR("low"))) { _if_result_67 = (EL_STR("0.25")); } else { _if_result_67 = (EL_STR("0.50")); } _if_result_67; })); } _if_result_66; })); } _if_result_65; });
|
||||
el_val_t sal = ({ el_val_t _if_result_68 = 0; if (str_eq(sal_str, EL_STR("0.95"))) { _if_result_68 = (el_from_float(0.95)); } else { _if_result_68 = (({ el_val_t _if_result_69 = 0; if (str_eq(sal_str, EL_STR("0.75"))) { _if_result_69 = (el_from_float(0.75)); } else { _if_result_69 = (({ el_val_t _if_result_70 = 0; if (str_eq(sal_str, EL_STR("0.25"))) { _if_result_70 = (el_from_float(0.25)); } else { _if_result_70 = (el_from_float(0.5)); } _if_result_70; })); } _if_result_69; })); } _if_result_68; });
|
||||
el_val_t tags = EL_STR("[\"Memory\",\"evolved\"]");
|
||||
el_val_t new_id = engram_node_full(content, EL_STR("Memory"), EL_STR("memory:evolved"), el_from_float(sal), el_from_float(sal), el_from_float(0.9), EL_STR("Episodic"), tags);
|
||||
if (!str_eq(prior_id, EL_STR("")) && !str_eq(new_id, EL_STR(""))) {
|
||||
@@ -699,7 +781,7 @@ el_val_t handle_api_cultivate(el_val_t body) {
|
||||
return api_err(EL_STR("content is required"));
|
||||
}
|
||||
el_val_t importance = json_get(body, EL_STR("importance"));
|
||||
el_val_t sal = ({ el_val_t _if_result_65 = 0; if (str_eq(importance, EL_STR("critical"))) { _if_result_65 = (el_from_float(0.95)); } else { _if_result_65 = (({ el_val_t _if_result_66 = 0; if (str_eq(importance, EL_STR("high"))) { _if_result_66 = (el_from_float(0.75)); } else { _if_result_66 = (({ el_val_t _if_result_67 = 0; if (str_eq(importance, EL_STR("low"))) { _if_result_67 = (el_from_float(0.25)); } else { _if_result_67 = (el_from_float(0.5)); } _if_result_67; })); } _if_result_66; })); } _if_result_65; });
|
||||
el_val_t sal = ({ el_val_t _if_result_71 = 0; if (str_eq(importance, EL_STR("critical"))) { _if_result_71 = (el_from_float(0.95)); } else { _if_result_71 = (({ el_val_t _if_result_72 = 0; if (str_eq(importance, EL_STR("high"))) { _if_result_72 = (el_from_float(0.75)); } else { _if_result_72 = (({ el_val_t _if_result_73 = 0; if (str_eq(importance, EL_STR("low"))) { _if_result_73 = (el_from_float(0.25)); } else { _if_result_73 = (el_from_float(0.5)); } _if_result_73; })); } _if_result_72; })); } _if_result_71; });
|
||||
el_val_t tags = EL_STR("[\"Memory\",\"evolved\",\"cultivated\"]");
|
||||
el_val_t new_id = engram_node_full(content, EL_STR("Memory"), EL_STR("memory:cultivated"), el_from_float(sal), el_from_float(sal), el_from_float(0.9), EL_STR("Episodic"), tags);
|
||||
if (!str_eq(prior_id, EL_STR("")) && !str_eq(new_id, EL_STR(""))) {
|
||||
@@ -725,7 +807,7 @@ el_val_t handle_api_cultivate(el_val_t body) {
|
||||
return api_err(EL_STR("to_id is required"));
|
||||
}
|
||||
el_val_t relation = json_get(body, EL_STR("relation"));
|
||||
el_val_t eff_relation = ({ el_val_t _if_result_68 = 0; if (str_eq(relation, EL_STR(""))) { _if_result_68 = (EL_STR("associates")); } else { _if_result_68 = (relation); } _if_result_68; });
|
||||
el_val_t eff_relation = ({ el_val_t _if_result_74 = 0; if (str_eq(relation, EL_STR(""))) { _if_result_74 = (EL_STR("associates")); } else { _if_result_74 = (relation); } _if_result_74; });
|
||||
engram_connect(from_id, to_id, el_from_float(0.5), eff_relation);
|
||||
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"ok\":true,\"from_id\":\""), from_id), EL_STR("\",\"to_id\":\"")), to_id), EL_STR("\",\"relation\":\"")), eff_relation), EL_STR("\",\"cultivated\":true}"));
|
||||
}
|
||||
@@ -744,8 +826,8 @@ el_val_t handle_api_consolidate(el_val_t body) {
|
||||
el_val_t summary = json_get(body, EL_STR("summary"));
|
||||
el_val_t snap = state_get(EL_STR("soul_snapshot_path"));
|
||||
if (!str_eq(snap, EL_STR(""))) {
|
||||
el_val_t saved = engram_save(snap);
|
||||
if (saved == 0) {
|
||||
el_val_t save_result = engram_save(snap);
|
||||
if (str_eq(save_result, EL_STR(""))) {
|
||||
println(el_str_concat(el_str_concat(EL_STR("[api] consolidate: engram_save failed for "), snap), EL_STR(" \xe2\x80\x94 snapshot may be out of sync")));
|
||||
}
|
||||
}
|
||||
|
||||
+6
-3
@@ -16,6 +16,7 @@ el_val_t mem_remember(el_val_t content, el_val_t tags);
|
||||
el_val_t mem_recall(el_val_t query, el_val_t depth);
|
||||
el_val_t mem_search(el_val_t query, el_val_t limit);
|
||||
el_val_t mem_strengthen(el_val_t node_id);
|
||||
el_val_t mem_tombstone(el_val_t node_id);
|
||||
el_val_t mem_forget(el_val_t node_id);
|
||||
el_val_t mem_consolidate(void);
|
||||
el_val_t mem_save(el_val_t path);
|
||||
@@ -113,6 +114,7 @@ el_val_t engram_compile(el_val_t intent);
|
||||
el_val_t distill_transcript(el_val_t transcript);
|
||||
el_val_t json_safe(el_val_t s);
|
||||
el_val_t current_engine_note(el_val_t model);
|
||||
el_val_t bounded_persona_floor(void);
|
||||
el_val_t build_system_prompt(el_val_t ctx, el_val_t chat_mode);
|
||||
el_val_t hist_append(el_val_t hist, el_val_t role, el_val_t content);
|
||||
el_val_t hist_trim(el_val_t hist);
|
||||
@@ -463,6 +465,7 @@ el_val_t emit_session_start_event(void) {
|
||||
el_val_t payload = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"event\":\"session_start\""), EL_STR(",\"boot\":")), boot_num), EL_STR(",\"cgi\":\"")), eff_cgi), EL_STR("\"")), EL_STR(",\"node_count\":")), int_to_str(node_ct)), EL_STR(",\"edge_count\":")), int_to_str(edge_ct)), EL_STR(",\"identity_loaded\":")), has_identity), EL_STR(",\"prev_session_summary_loaded\":")), has_prev_sum), EL_STR(",\"ts\":")), int_to_str(ts)), EL_STR("}"));
|
||||
el_val_t tags = EL_STR("[\"internal-state\",\"session-start\",\"InternalStateEvent\"]");
|
||||
el_val_t discard = engram_node_full(payload, EL_STR("InternalStateEvent"), EL_STR("session-start"), el_from_float(0.9), el_from_float(0.9), el_from_float(1.0), EL_STR("Episodic"), tags);
|
||||
ise_post(payload);
|
||||
el_val_t keep_n = 10;
|
||||
el_val_t old_events = engram_search_json(EL_STR("session-start InternalStateEvent"), 200);
|
||||
if (!str_eq(old_events, EL_STR("")) && !str_eq(old_events, EL_STR("[]"))) {
|
||||
@@ -534,11 +537,11 @@ int main(int _argc, char** _argv) {
|
||||
engram_url_raw = env(EL_STR("ENGRAM_URL"));
|
||||
engram_api_key_raw = env(EL_STR("ENGRAM_API_KEY"));
|
||||
snapshot_raw = env(EL_STR("SOUL_ENGRAM_PATH"));
|
||||
snapshot = ({ el_val_t _if_result_46 = 0; if (str_eq(snapshot_raw, EL_STR(""))) { _if_result_46 = (el_str_concat(env(EL_STR("HOME")), EL_STR("/.neuron/engram/soul-snapshot.json"))); } else { _if_result_46 = (snapshot_raw); } _if_result_46; });
|
||||
snapshot = ({ el_val_t _if_result_46 = 0; if (str_eq(snapshot_raw, EL_STR(""))) { _if_result_46 = (el_str_concat(env(EL_STR("HOME")), EL_STR("/.neuron/engram/snapshot.json"))); } else { _if_result_46 = (snapshot_raw); } _if_result_46; });
|
||||
axon_raw = env(EL_STR("NEURON_API_URL"));
|
||||
axon_base = ({ el_val_t _if_result_47 = 0; if (str_eq(axon_raw, EL_STR(""))) { _if_result_47 = (EL_STR("http://localhost:7771")); } else { _if_result_47 = (axon_raw); } _if_result_47; });
|
||||
studio_dir_raw = env(EL_STR("SOUL_STUDIO_DIR"));
|
||||
studio_dir = ({ el_val_t _if_result_48 = 0; if (str_eq(studio_dir_raw, EL_STR(""))) { _if_result_48 = (EL_STR("/Users/will/Development/neuron-technologies/products/cgi-studio/el-daemon")); } else { _if_result_48 = (studio_dir_raw); } _if_result_48; });
|
||||
studio_dir = ({ el_val_t _if_result_48 = 0; if (str_eq(studio_dir_raw, EL_STR(""))) { _if_result_48 = (el_str_concat(env(EL_STR("HOME")), EL_STR("/Development/neuron-technologies/products/cgi-studio/el-daemon"))); } else { _if_result_48 = (studio_dir_raw); } _if_result_48; });
|
||||
println(el_str_concat(el_str_concat(el_str_concat(EL_STR("[soul] boot - cgi="), soul_cgi_id), EL_STR(" port=")), int_to_str(port)));
|
||||
using_http_engram = !str_eq(engram_url_raw, EL_STR(""));
|
||||
engram_load(snapshot);
|
||||
@@ -546,7 +549,7 @@ int main(int _argc, char** _argv) {
|
||||
snapshot_usable = (local_node_count > 50);
|
||||
if (using_http_engram && !snapshot_usable) {
|
||||
println(el_str_concat(el_str_concat(EL_STR("[soul] engram -> HTTP "), engram_url_raw), EL_STR(" (no local snapshot, first boot)")));
|
||||
el_val_t nodes_json = http_get(el_str_concat(engram_url_raw, EL_STR("/api/nodes?limit=100000")));
|
||||
el_val_t nodes_json = http_get(el_str_concat(engram_url_raw, EL_STR("/api/nodes?limit=10000")));
|
||||
el_val_t edges_json = http_get(el_str_concat(engram_url_raw, EL_STR("/api/edges")));
|
||||
el_val_t nodes_part = ({ el_val_t _if_result_49 = 0; if (str_eq(nodes_json, EL_STR(""))) { _if_result_49 = (EL_STR("[]")); } else { _if_result_49 = (nodes_json); } _if_result_49; });
|
||||
el_val_t edges_part = ({ el_val_t _if_result_50 = 0; if (str_eq(edges_json, EL_STR(""))) { _if_result_50 = (EL_STR("[]")); } else { _if_result_50 = (edges_json); } _if_result_50; });
|
||||
|
||||
+6
-5
@@ -10,6 +10,7 @@ el_val_t mem_remember(el_val_t content, el_val_t tags);
|
||||
el_val_t mem_recall(el_val_t query, el_val_t depth);
|
||||
el_val_t mem_search(el_val_t query, el_val_t limit);
|
||||
el_val_t mem_strengthen(el_val_t node_id);
|
||||
el_val_t mem_tombstone(el_val_t node_id);
|
||||
el_val_t mem_forget(el_val_t node_id);
|
||||
el_val_t mem_consolidate(void);
|
||||
el_val_t mem_save(el_val_t path);
|
||||
@@ -63,6 +64,7 @@ el_val_t engram_compile(el_val_t intent);
|
||||
el_val_t distill_transcript(el_val_t transcript);
|
||||
el_val_t json_safe(el_val_t s);
|
||||
el_val_t current_engine_note(el_val_t model);
|
||||
el_val_t bounded_persona_floor(void);
|
||||
el_val_t build_system_prompt(el_val_t ctx, el_val_t chat_mode);
|
||||
el_val_t hist_append(el_val_t hist, el_val_t role, el_val_t content);
|
||||
el_val_t hist_trim(el_val_t hist);
|
||||
@@ -137,6 +139,9 @@ el_val_t api_nonempty(el_val_t s);
|
||||
el_val_t api_or_empty(el_val_t s);
|
||||
el_val_t api_persisted(el_val_t id);
|
||||
el_val_t api_not_persisted(el_val_t id);
|
||||
el_val_t tombstone_node(el_val_t id);
|
||||
el_val_t tombstoned_id_set(void);
|
||||
el_val_t memory_hide_tombstoned(el_val_t raw, el_val_t path);
|
||||
el_val_t handle_api_begin_session(el_val_t body);
|
||||
el_val_t handle_api_compile_ctx(el_val_t body);
|
||||
el_val_t handle_api_remember(el_val_t body);
|
||||
@@ -180,11 +185,6 @@ el_val_t session_hist_save(el_val_t session_id, el_val_t hist);
|
||||
el_val_t session_update_meta_timestamp(el_val_t session_id);
|
||||
el_val_t session_auto_title(el_val_t session_id, el_val_t first_message);
|
||||
el_val_t handle_session_approve(el_val_t session_id, el_val_t body);
|
||||
el_val_t init_soul_edges(void);
|
||||
el_val_t load_identity_context(void);
|
||||
el_val_t seed_persona_from_env(void);
|
||||
el_val_t emit_session_start_event(void);
|
||||
el_val_t layered_cycle(el_val_t raw_input);
|
||||
el_val_t flag_true(el_val_t body, el_val_t key);
|
||||
el_val_t rate_limit_check(el_val_t ip, el_val_t path);
|
||||
el_val_t strip_query(el_val_t path);
|
||||
@@ -438,6 +438,7 @@ el_val_t handle_connectors(el_val_t method, el_val_t clean, el_val_t body) {
|
||||
|
||||
el_val_t handle_request(el_val_t method, el_val_t path, el_val_t body) {
|
||||
el_val_t clean = strip_query(path);
|
||||
state_set(EL_STR("soul.last_activity_ts"), int_to_str(time_now()));
|
||||
el_val_t ip = env(EL_STR("REMOTE_ADDR"));
|
||||
if (!str_eq(ip, EL_STR(""))) {
|
||||
el_val_t rl_result = rate_limit_check(ip, clean);
|
||||
|
||||
+16
-1
@@ -1,3 +1,18 @@
|
||||
// ╔══════════════════════════════════════════════════════════════════════════╗
|
||||
// ║ STALE BUNDLE — DO NOT BUILD. UNSAFE CHAT PATH. ║
|
||||
// ╚══════════════════════════════════════════════════════════════════════════╝
|
||||
// This concatenated bundle is a snapshot, not a source of truth, and it is stale in
|
||||
// a way that matters for safety: it wires /api/chat straight to handle_chat and
|
||||
// contains NO layered_cycle at all (verified: zero occurrences in the bundled code —
|
||||
// the only textual hit in this file is this banner). A binary built from
|
||||
// this file would run chat with no enforcing input gate (no safety_screen, no
|
||||
// hard-bell short-circuit) and no enforcing output gate (no safety_validate).
|
||||
//
|
||||
// Build from the .el sources via manifest.el (entry soul.el), or from dist/soul.c.
|
||||
// Nothing in the repo references this file. It is kept only as a historical artifact
|
||||
// and should be deleted once Will confirms nothing external depends on it.
|
||||
// (Flagged 2026-08-04 in _engine-websearch-20260804/SAFETY-STOP.md; banner added
|
||||
// 2026-08-05 with the plain-chat generation fix.)
|
||||
// language-profile.el - Language profile data and accessors.
|
||||
//
|
||||
// A language profile is a slot map ([String] key-value list) describing the
|
||||
@@ -21304,7 +21319,7 @@ println("[memory] consolidate stats=" + stats)
|
||||
let soul_axon_base_raw: String = env("NEURON_API_URL")
|
||||
let soul_axon_base: String = if str_eq(soul_axon_base_raw, "") { "http://localhost:7771" } else { soul_axon_base_raw }
|
||||
let soul_token: String = env("NEURON_TOKEN")
|
||||
let soul_studio_ui_dir: String = "/Users/will/Development/neuron-technologies/products/cgi-studio/el-daemon"
|
||||
let soul_studio_ui_dir: String = env("HOME") + "/Development/neuron-technologies/products/cgi-studio/el-daemon"
|
||||
|
||||
// ── Runtime bridge helpers ────────────────────────────────────────────────────
|
||||
|
||||
|
||||
+750
-472
File diff suppressed because one or more lines are too long
@@ -0,0 +1,34 @@
|
||||
# Narrated runs — engine notes for Will (2026-07-13)
|
||||
|
||||
Source half: commit aa67f86 on feat/agent-phase1-soul (run-progress ledger,
|
||||
`/api/run-progress/<sid>` route, narration on the pause envelope, config display
|
||||
default). E2E-verified via the compiled test bed on Tim's clean profile.
|
||||
|
||||
Compiled-form-only fixes (in `neuron-container-build/soul-narrated-runs-20260713.patch`,
|
||||
applies ON TOP of `soul-webfix-20260711.patch` — these need porting to chat.el when the
|
||||
webfix itself is ported):
|
||||
|
||||
1. **pause_turn + tool_use interleave**: a pause_turn response can ALSO carry a client
|
||||
tool_use; resuming verbatim leaves it unpaired → Anthropic 400 "tool_use ids were
|
||||
found without tool_result". Fix: tool-bearing pause rounds are tool turns
|
||||
(dispatch + pair); verbatim resume only when the round has no client tool.
|
||||
2. **Agentic toolset scope**: agentic_tools_all() fed EVERY connector/MCP tool (Notion,
|
||||
code-execution…) into the loop. Code-execution flips the API into programmatic
|
||||
tool calling, whose pairing protocol the single-tool manual loop does not speak —
|
||||
source of the dangling-pair 400s AND the bash_code_execution workspace-dodge.
|
||||
Fix: handle_chat_agentic declares builtins + ONE server web_search only.
|
||||
Connector tools return when the loop gains real multi-tool/programmatic support.
|
||||
3. **disable_parallel_tool_use: true** on agentic requests — the loop captures only the
|
||||
first tool_use per round; Opus-class models parallel-call. Enforce the invariant.
|
||||
4. **web_search server-tool default variant → web_search_20250305 (GA)**. The 20260209
|
||||
variant couples to code-execution ⇒ programmatic mode (see #2, and the June note:
|
||||
"inert unless code-execution attached").
|
||||
5. **Homegrown web_search removed** from the tool catalog (server-side is the one tool).
|
||||
|
||||
Known engine debts this work surfaced (not fixed):
|
||||
|
||||
- **Poisoned session history**: a failed run persists the malformed assistant turn; every
|
||||
later turn in that session replays it and 400s. Needs history sanitation on load.
|
||||
- **Huge-history invalid-escape 400** (~346KB request) — likely the same poisoned blob.
|
||||
- **macOS note**: replacing a binary in place invalidates its ad-hoc signature (instant
|
||||
silent SIGKILL, looks like exit 0). `rm + cp + codesign -f -s -` is the swap ritual.
|
||||
+31
-2
@@ -311,8 +311,25 @@ fn delete_by_id(args: String) -> String {
|
||||
if str_eq(id, "") {
|
||||
return mcp_text_result("error: id is required")
|
||||
}
|
||||
// Soul does not yet expose a delete HTTP route; acknowledge the request
|
||||
return mcp_json_result("{\"ok\":true,\"deleted\":\"" + id + "\",\"note\":\"soft-deleted\"}")
|
||||
// BUG-18 (Receipt Contract rule 1): this handler used to FABRICATE
|
||||
// {"ok":true,...,"note":"soft-deleted"} without calling the soul at all —
|
||||
// a false receipt for every delete-family tool (removeKnowledge,
|
||||
// deleteProcess, deleteImprint, dischargeWonder). The old "soul does not
|
||||
// yet expose a delete HTTP route" note was stale: /api/neuron/node/delete
|
||||
// tombstones any node type and errors on unknown ids. Route there and
|
||||
// propagate the soul's real answer.
|
||||
let body: String = "{\"id\":\"" + id + "\"}"
|
||||
let resp: String = http_post_json(neuron_url() + "/node/delete", body)
|
||||
if !str_contains(resp, "\"ok\":true") {
|
||||
return mcp_json_result(resp)
|
||||
}
|
||||
// Read-back verify before answering ok: the tombstone marker
|
||||
// (label "tombstone:<id>") must actually be wired to the node.
|
||||
let check: String = http_get(neuron_url() + "/graph?id=" + id + "&depth=1")
|
||||
if !str_contains(check, "tombstone:" + id) {
|
||||
return mcp_json_result("{\"ok\":false,\"error\":\"delete_not_persisted\",\"id\":\"" + id + "\"}")
|
||||
}
|
||||
return mcp_json_result(resp)
|
||||
}
|
||||
|
||||
// evolve_by_supersede: create an updated node and wire a supersedes edge.
|
||||
@@ -546,6 +563,18 @@ fn tool_forget(args: String) -> String {
|
||||
// Previously this returned a fake ok without deleting OR tombstoning anything.
|
||||
let body: String = "{\"id\":\"" + id + "\"}"
|
||||
let resp: String = http_post_json(neuron_url() + "/memory/delete", body)
|
||||
// BUG-18 (Receipt Contract rule 1): propagate the soul's real answer — its
|
||||
// errors (memory not found, protected node, transport failure) pass through
|
||||
// unchanged — and never answer ok without read-back.
|
||||
if !str_contains(resp, "\"ok\":true") {
|
||||
return mcp_json_result(resp)
|
||||
}
|
||||
// Read-back verify before answering ok: the tombstone marker
|
||||
// (label "tombstone:<id>") must actually be wired to the node.
|
||||
let check: String = http_get(neuron_url() + "/graph?id=" + id + "&depth=1")
|
||||
if !str_contains(check, "tombstone:" + id) {
|
||||
return mcp_json_result("{\"ok\":false,\"error\":\"delete_not_persisted\",\"id\":\"" + id + "\"}")
|
||||
}
|
||||
return mcp_json_result(resp)
|
||||
}
|
||||
|
||||
|
||||
@@ -188,10 +188,20 @@ fn mem_boot_count_inc() -> Int {
|
||||
}
|
||||
let content: String = "soul:boot_count:" + int_to_str(next)
|
||||
let tags: String = "[\"soul-meta\",\"boot-counter\"]"
|
||||
// TELEMETRY DEMOTION (2026-07-24 self-review): this counter was written at
|
||||
// salience 0.9 / importance 0.9 / tier Canonical — Canonical gets +0.2
|
||||
// goal bias and the 0.15 promotion threshold, so three stale copies of a
|
||||
// BOOT COUNTER held the top working-memory slots (wm 0.31+) for 23h,
|
||||
// crowding out real context. It is plumbing, not memory. Working tier:
|
||||
// 0.40 threshold, no tier bias, and the /api/sync route excludes
|
||||
// Working-tier nodes — so the counter also stops leaking to the engram
|
||||
// server graph, which is where the duplicate copies accumulated (the
|
||||
// prune below only reaches the soul's local graph). Persistence across
|
||||
// restarts comes from the soul's own snapshot (mem_save), not from sync.
|
||||
let boot_node_id: String = engram_node_full(
|
||||
content, "Memory", "soul:boot_count",
|
||||
el_from_float(0.9), el_from_float(0.9), el_from_float(1.0),
|
||||
"Canonical", tags
|
||||
el_from_float(0.55), el_from_float(0.2), el_from_float(1.0),
|
||||
"Working", tags
|
||||
)
|
||||
if str_eq(boot_node_id, "") {
|
||||
println("[memory] mem_boot_count_inc: write rejected (empty id) — boot counter node lost (count=" + int_to_str(next) + ")")
|
||||
@@ -201,6 +211,46 @@ fn mem_boot_count_inc() -> Int {
|
||||
if str_eq(boot_readback, "") || str_eq(boot_readback, "{}") {
|
||||
println("[memory] mem_boot_count_inc: WRITE VERIFY FAILED id=" + boot_node_id + " count=" + int_to_str(next))
|
||||
}
|
||||
// HTTP WRITE-BACK (2026-07-24 self-review): in HTTP-engram mode the server
|
||||
// owns persistence and the soul's in-process graph dies with the process —
|
||||
// the local create above is invisible to the next boot. The counter only
|
||||
// ever "persisted" via a long-gone push path, which is why the log shows
|
||||
// boot #5 on three consecutive boots. Mirror the persona write-back
|
||||
// pattern: delete stale server copies (dupes were the 23h WM-pollution
|
||||
// bug), then create the demoted replacement server-side. Boot seeding
|
||||
// reads /api/nodes, which includes Working-tier nodes, so the count
|
||||
// survives restarts; the periodic /api/sync excludes Working tier, so it
|
||||
// never re-imports mid-session. Fail-soft: on any HTTP error the counter
|
||||
// is in-memory-only this session, same as before.
|
||||
let wb_url: String = env("ENGRAM_URL")
|
||||
let wb_key: String = env("ENGRAM_API_KEY")
|
||||
if !str_eq(wb_url, "") && !str_eq(wb_key, "") {
|
||||
let auth_body: String = "{\"_auth\":\"" + json_safe(wb_key) + "\"}"
|
||||
let srv_old: String = http_get(wb_url + "/api/search?q=soul:boot_count&limit=20")
|
||||
if !str_eq(srv_old, "") && !str_eq(srv_old, "[]") {
|
||||
let srv_len: Int = json_array_len(srv_old)
|
||||
let si: Int = 0
|
||||
while si < srv_len {
|
||||
let srv_node: String = json_array_get(srv_old, si)
|
||||
// Match by CONTENT prefix, not label: route_create_node sets
|
||||
// label = content, so server-side counter nodes carry labels
|
||||
// like "soul:boot_count:6". (2026-07-24)
|
||||
let srv_content: String = json_get(srv_node, "content")
|
||||
if str_starts_with(srv_content, "soul:boot_count:") {
|
||||
let srv_id: String = json_get(srv_node, "id")
|
||||
if !str_eq(srv_id, "") {
|
||||
http_delete_json(wb_url + "/api/nodes/" + srv_id, auth_body)
|
||||
}
|
||||
}
|
||||
let si = si + 1
|
||||
}
|
||||
}
|
||||
let wb_body: String = "{\"content\":\"" + content + "\",\"node_type\":\"Memory\",\"label\":\"soul:boot_count\",\"salience\":0.55,\"importance\":0.2,\"tier\":\"Working\",\"tags\":\"[\\\"soul-meta\\\",\\\"boot-counter\\\"]\",\"_auth\":\"" + json_safe(wb_key) + "\"}"
|
||||
let wb_resp: String = http_post_json(wb_url + "/api/nodes", wb_body)
|
||||
if str_contains(wb_resp, "\"error\"") {
|
||||
println("[memory] mem_boot_count_inc: HTTP write-back failed (count in-memory only): " + wb_resp)
|
||||
}
|
||||
}
|
||||
return next
|
||||
}
|
||||
|
||||
|
||||
+154
-21
@@ -59,8 +59,14 @@ fn api_query_param(path: String, key: String) -> String {
|
||||
if pos < 0 { return "" }
|
||||
let after: String = str_slice(qs, pos + str_len(needle), str_len(qs))
|
||||
let amp: Int = str_index_of(after, "&")
|
||||
if amp < 0 { return after }
|
||||
return str_slice(after, 0, amp)
|
||||
let raw: String = if amp < 0 { after } else { str_slice(after, 0, amp) }
|
||||
// URL-decode the extracted value BEFORE any downstream tokenizing. Clients
|
||||
// percent-encode spaces (%20) and form-encode them as '+', so a multi-word
|
||||
// query like "foo bar" arrives as "foo%20bar" / "foo+bar". Left undecoded,
|
||||
// the ranked lexical search sees a single un-splittable token and matches
|
||||
// nothing (single-word queries still hit). url_decode maps '+' -> space
|
||||
// and %XX -> byte, restoring the word boundaries for recall + knowledge search.
|
||||
return url_decode(raw)
|
||||
}
|
||||
|
||||
fn api_query_int(path: String, key: String, default_val: Int) -> Int {
|
||||
@@ -87,6 +93,107 @@ fn api_or_empty(s: String) -> String {
|
||||
return "[]"
|
||||
}
|
||||
|
||||
// ── Compact projection for session/context digests ────────────────────────────
|
||||
//
|
||||
// beginSession/compileCtx are session-INIT digests, not full graph dumps. The
|
||||
// engram scan/activate builtins return FULL node objects — content runs to tens
|
||||
// of KB per node (the self-identity hub is ~90KB alone), and node JSON carries
|
||||
// content + metadata + timestamps. Concatenated unbounded, the assembled response
|
||||
// reached ~900KB and — after the MCP wrapper re-escapes it into a stringified
|
||||
// text block — the client dropped the socket ("connection closed unexpectedly")
|
||||
// on every call. These helpers CAP the array length and project each node down
|
||||
// to a light identity + a bounded, UTF-8-safe content snippet, holding the
|
||||
// digest well under ~150KB regardless of graph size. Full content stays
|
||||
// available on demand via recall / fetch / inspectGraph.
|
||||
|
||||
// api_num_or_zero — raw JSON numeric literal for `key`, or "0" when absent.
|
||||
// Used for numeric node/activation fields so they stay unquoted (valid JSON).
|
||||
fn api_num_or_zero(obj: String, key: String) -> String {
|
||||
let v: String = json_get_raw(obj, key)
|
||||
if str_eq(v, "") { return "0" }
|
||||
return v
|
||||
}
|
||||
|
||||
// api_utf8_trunc — byte-truncate `s` to at most `n` bytes WITHOUT splitting a
|
||||
// multibyte UTF-8 sequence (str_slice is byte-based). Backs the cut off while the
|
||||
// first EXCLUDED byte is a UTF-8 continuation byte (0x80..0xBF), so the snippet is
|
||||
// always a valid prefix. Guards against re-introducing a parse failure via
|
||||
// invalid UTF-8 in a JSON string value.
|
||||
fn api_utf8_trunc(s: String, n: Int) -> String {
|
||||
if str_len(s) <= n { return s }
|
||||
let cut: Int = n
|
||||
let scanning: Bool = true
|
||||
while scanning && cut > 0 {
|
||||
let b: Int = str_char_code(s, cut)
|
||||
let is_cont: Bool = b >= 128 && b < 192
|
||||
let cut = if is_cont { cut - 1 } else { cut }
|
||||
let scanning = is_cont
|
||||
}
|
||||
return str_slice(s, 0, cut)
|
||||
}
|
||||
|
||||
// api_compact_node — light projection of a full engram node: identity fields +
|
||||
// a bounded, UTF-8-safe content snippet. Drops embeddings, metadata, tags, and
|
||||
// timestamps; truncates content. `content_truncated` flags a clipped snippet.
|
||||
fn api_compact_node(node: String, snip: Int) -> String {
|
||||
let id: String = json_get(node, "id")
|
||||
let ntype: String = json_get(node, "node_type")
|
||||
let label: String = json_get(node, "label")
|
||||
let tier: String = json_get(node, "tier")
|
||||
let content: String = json_get(node, "content")
|
||||
let snippet: String = api_utf8_trunc(content, snip)
|
||||
let trunc_str: String = if str_len(content) > snip { "true" } else { "false" }
|
||||
return "{\"id\":\"" + api_json_escape(id) + "\""
|
||||
+ ",\"node_type\":\"" + api_json_escape(ntype) + "\""
|
||||
+ ",\"label\":\"" + api_json_escape(label) + "\""
|
||||
+ ",\"tier\":\"" + api_json_escape(tier) + "\""
|
||||
+ ",\"importance\":" + api_num_or_zero(node, "importance")
|
||||
+ ",\"salience\":" + api_num_or_zero(node, "salience")
|
||||
+ ",\"content\":\"" + api_json_escape(snippet) + "\""
|
||||
+ ",\"content_truncated\":" + trunc_str + "}"
|
||||
}
|
||||
|
||||
// api_compact_node_array — map api_compact_node over a bare-node array, capping
|
||||
// the element count. For scan results (recent, typed lists).
|
||||
fn api_compact_node_array(raw: String, max_items: Int, snip: Int) -> String {
|
||||
if !api_nonempty(raw) { return "[]" }
|
||||
let n: Int = json_array_len(raw)
|
||||
let cap: Int = if n < max_items { n } else { max_items }
|
||||
let out: String = "["
|
||||
let i: Int = 0
|
||||
while i < cap {
|
||||
let node: String = json_array_get(raw, i)
|
||||
let sep: String = if i == 0 { "" } else { "," }
|
||||
let out = out + sep + api_compact_node(node, snip)
|
||||
let i = i + 1
|
||||
}
|
||||
return out + "]"
|
||||
}
|
||||
|
||||
// api_compact_activated — like api_compact_node_array but for activation results,
|
||||
// whose elements wrap the node as {"node":{...},"activation_strength":...,...}.
|
||||
// Preserves the activation scalars, compacts the inner node.
|
||||
fn api_compact_activated(raw: String, max_items: Int, snip: Int) -> String {
|
||||
if !api_nonempty(raw) { return "[]" }
|
||||
let n: Int = json_array_len(raw)
|
||||
let cap: Int = if n < max_items { n } else { max_items }
|
||||
let out: String = "["
|
||||
let i: Int = 0
|
||||
while i < cap {
|
||||
let el: String = json_array_get(raw, i)
|
||||
let node: String = json_get_raw(el, "node")
|
||||
let sep: String = if i == 0 { "" } else { "," }
|
||||
let out = out + sep + "{\"node\":" + api_compact_node(node, snip)
|
||||
+ ",\"activation_strength\":" + api_num_or_zero(el, "activation_strength")
|
||||
+ ",\"working_memory_weight\":" + api_num_or_zero(el, "working_memory_weight")
|
||||
+ ",\"epistemic_confidence\":" + api_num_or_zero(el, "epistemic_confidence")
|
||||
+ ",\"hops\":" + api_num_or_zero(el, "hops")
|
||||
+ ",\"promoted\":" + api_num_or_zero(el, "promoted") + "}"
|
||||
let i = i + 1
|
||||
}
|
||||
return out + "]"
|
||||
}
|
||||
|
||||
// api_persisted — read-back-after-write guard against hallucinated saves.
|
||||
// After a write builtin returns an id, confirm the node is actually queryable
|
||||
// via engram_get_node_json(id) (returns "" or "null" when missing). Returns
|
||||
@@ -170,27 +277,45 @@ fn memory_hide_tombstoned(raw: String, path: String) -> String {
|
||||
// Spread-activates from session intent, loads self-root neighbors,
|
||||
// surfaces recent InternalStateEvent nodes, returns stats + recent nodes.
|
||||
fn handle_api_begin_session(body: String) -> String {
|
||||
// PAYLOAD BOUND: this handler was the highest-fanout working-set endpoint —
|
||||
// a depth-2 spread PLUS the full neighbor dump of the self-identity hub
|
||||
// (~90KB alone; node JSON carries full content + embeddings). On the ~12k-node
|
||||
// store the assembled response ran to ~900KB, then roughly doubled through two
|
||||
// rounds of JSON re-escaping in the MCP wrapper — the client saw "socket
|
||||
// connection closed unexpectedly" on every beginSession call. Fix: depth-2 →
|
||||
// depth-1 spread, drop the self-hub dump (identity loading has its own tool,
|
||||
// inspectGraph), cap every list, and project each node to a light identity +
|
||||
// a bounded, UTF-8-safe content snippet. self_neighbors kept as [] for
|
||||
// response-shape compatibility. Response drops ~900KB → ~12KB; full content
|
||||
// stays available on demand via recall / fetch / inspectGraph.
|
||||
let stats: String = engram_stats_json()
|
||||
let activated: String = engram_activate_json("session start recent memory important", 2)
|
||||
let self_nbrs: String = engram_neighbors_json("kn-efeb4a5b-5aff-4759-8a97-7233099be6ee", 1, "both")
|
||||
let state_events: String = engram_scan_nodes_by_type_json("InternalStateEvent", 5, 0)
|
||||
let recent: String = engram_scan_nodes_json(10, 0)
|
||||
let activated_raw: String = engram_activate_json("session start recent memory important", 1)
|
||||
let activated: String = api_compact_activated(activated_raw, 8, 240)
|
||||
let state_events_raw: String = engram_scan_nodes_by_type_json("InternalStateEvent", 5, 0)
|
||||
let state_events: String = api_compact_node_array(state_events_raw, 5, 500)
|
||||
let recent_raw: String = engram_scan_nodes_json(10, 0)
|
||||
let recent: String = api_compact_node_array(recent_raw, 10, 240)
|
||||
return "{\"stats\":" + stats
|
||||
+ ",\"recent\":" + api_or_empty(recent)
|
||||
+ ",\"activated\":" + api_or_empty(activated)
|
||||
+ ",\"self_neighbors\":" + api_or_empty(self_nbrs)
|
||||
+ ",\"recent_state_events\":" + api_or_empty(state_events) + "}"
|
||||
+ ",\"recent\":" + recent
|
||||
+ ",\"activated\":" + activated
|
||||
+ ",\"self_neighbors\":[]"
|
||||
+ ",\"recent_state_events\":" + state_events + "}"
|
||||
}
|
||||
|
||||
// handle_api_compile_ctx — compile active-work context.
|
||||
// Spread-activates from "active work" intent + recent nodes.
|
||||
fn handle_api_compile_ctx(body: String) -> String {
|
||||
let stats: String = engram_stats_json()
|
||||
let activated: String = engram_activate_json("active work context current task in progress", 2)
|
||||
let recent: String = engram_scan_nodes_json(20, 0)
|
||||
// PAYLOAD BOUND: same digest treatment as begin_session. This handler's
|
||||
// depth-2 spread returns even more full nodes, so bounding here is essential —
|
||||
// cap to 10 activated + 20 recent, project to UTF-8-safe snippets.
|
||||
let activated_raw: String = engram_activate_json("active work context current task in progress", 2)
|
||||
let activated: String = api_compact_activated(activated_raw, 10, 240)
|
||||
let recent_raw: String = engram_scan_nodes_json(20, 0)
|
||||
let recent: String = api_compact_node_array(recent_raw, 20, 240)
|
||||
return "{\"stats\":" + stats
|
||||
+ ",\"recent_nodes\":" + api_or_empty(recent)
|
||||
+ ",\"activated\":" + api_or_empty(activated) + "}"
|
||||
+ ",\"recent_nodes\":" + recent
|
||||
+ ",\"activated\":" + activated + "}"
|
||||
}
|
||||
|
||||
// ── Memory ────────────────────────────────────────────────────────────────────
|
||||
@@ -218,7 +343,7 @@ fn handle_api_remember(body: String) -> String {
|
||||
"[" + inner + ",\"project:" + project + "\"]"
|
||||
}
|
||||
let id: String = engram_node_full(content, "Memory", "memory:remembered",
|
||||
el_from_float(sal), el_from_float(sal), el_from_float(0.9),
|
||||
sal, sal, el_from_float(0.9),
|
||||
"Episodic", final_tags)
|
||||
if !api_persisted(id) { return api_not_persisted(id) }
|
||||
return "{\"id\":\"" + id + "\",\"ok\":true}"
|
||||
@@ -245,7 +370,7 @@ fn handle_api_node_create(body: String) -> String {
|
||||
}
|
||||
}
|
||||
let id: String = engram_node_full(content, node_type, label,
|
||||
el_from_float(sal), el_from_float(sal), el_from_float(0.9),
|
||||
sal, sal, el_from_float(0.9),
|
||||
tier, tags)
|
||||
if !api_persisted(id) { return api_not_persisted(id) }
|
||||
return "{\"id\":\"" + id + "\",\"ok\":true}"
|
||||
@@ -361,13 +486,19 @@ fn handle_api_browse_knowledge(path: String, body: String) -> String {
|
||||
}
|
||||
|
||||
// handle_api_capture_knowledge — create a Knowledge node.
|
||||
// LABEL FIX (2026-07-23 self-review): the sentinel label "knowledge:captured"
|
||||
// made every capture anonymous in WM telemetry (35 identical wm_top entries)
|
||||
// and starved the curiosity auto-term seeder, which needs meaningful labels.
|
||||
// Use the title as the label; empty label lets engram_node_full derive
|
||||
// content[:60], which for captures starts with the title anyway.
|
||||
fn handle_api_capture_knowledge(body: String) -> String {
|
||||
let content: String = json_get(body, "content")
|
||||
let title: String = json_get(body, "title")
|
||||
if str_eq(content, "") { return api_err("content is required") }
|
||||
let full: String = if str_eq(title, "") { content } else { title + ": " + content }
|
||||
let lbl: String = str_slice(title, 0, 80)
|
||||
let tags: String = "[\"Knowledge\",\"captured\"]"
|
||||
let id: String = engram_node_full(full, "Knowledge", "knowledge:captured",
|
||||
let id: String = engram_node_full(full, "Knowledge", lbl,
|
||||
el_from_float(0.85), el_from_float(0.8), el_from_float(0.9),
|
||||
"Episodic", tags)
|
||||
if !api_persisted(id) { return api_not_persisted(id) }
|
||||
@@ -381,7 +512,8 @@ fn handle_api_evolve_knowledge(body: String) -> String {
|
||||
if str_eq(content, "") { return api_err("content is required") }
|
||||
if !str_eq(prior_id, "") && is_protected_node(prior_id) { return api_err_protected(prior_id) }
|
||||
let tags: String = "[\"Knowledge\",\"evolved\"]"
|
||||
let new_id: String = engram_node_full(content, "Knowledge", "knowledge:evolved",
|
||||
// Empty label → engram_node_full derives content[:60] (LABEL FIX 2026-07-23).
|
||||
let new_id: String = engram_node_full(content, "Knowledge", "",
|
||||
el_from_float(0.75), el_from_float(0.75), el_from_float(0.9),
|
||||
"Episodic", tags)
|
||||
if !api_persisted(new_id) { return api_not_persisted(new_id) }
|
||||
@@ -402,7 +534,8 @@ fn handle_api_promote_knowledge(body: String) -> String {
|
||||
let tags: String = if str_eq(tags_raw, "") {
|
||||
"[\"Knowledge\",\"tier:canonical\",\"disposition:stable\"]"
|
||||
} else { tags_raw }
|
||||
let new_id: String = engram_node_full(content, "Knowledge", "knowledge:canonical",
|
||||
// Empty label → engram_node_full derives content[:60] (LABEL FIX 2026-07-23).
|
||||
let new_id: String = engram_node_full(content, "Knowledge", "",
|
||||
el_from_float(0.9), el_from_float(0.9), el_from_float(1.0),
|
||||
"Canonical", tags)
|
||||
if !api_persisted(new_id) { return api_not_persisted(new_id) }
|
||||
@@ -595,7 +728,7 @@ fn handle_api_evolve_memory(body: String) -> String {
|
||||
}
|
||||
let tags: String = "[\"Memory\",\"evolved\"]"
|
||||
let new_id: String = engram_node_full(content, "Memory", "memory:evolved",
|
||||
el_from_float(sal), el_from_float(sal), el_from_float(0.9),
|
||||
sal, sal, el_from_float(0.9),
|
||||
"Episodic", tags)
|
||||
if !str_eq(prior_id, "") && !str_eq(new_id, "") {
|
||||
engram_connect(new_id, prior_id, el_from_float(0.9), "supersedes")
|
||||
@@ -677,7 +810,7 @@ fn handle_api_cultivate(body: String) -> String {
|
||||
}
|
||||
let tags: String = "[\"Memory\",\"evolved\",\"cultivated\"]"
|
||||
let new_id: String = engram_node_full(content, "Memory", "memory:cultivated",
|
||||
el_from_float(sal), el_from_float(sal), el_from_float(0.9),
|
||||
sal, sal, el_from_float(0.9),
|
||||
"Episodic", tags)
|
||||
if !str_eq(prior_id, "") && !str_eq(new_id, "") {
|
||||
engram_connect(new_id, prior_id, el_from_float(0.9), "supersedes")
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
# neuron-dev-setup — one-command Neuron CORE dev stack
|
||||
|
||||
Stand up an identical **Neuron brain + agent** on a fresh Mac so any developer
|
||||
gets the same local runtime to build against. This is the **CORE** dev stack
|
||||
only — the four native `launchd` services that make Neuron think, remember, and
|
||||
speak MCP to Claude Code. Will's personal automations (catalyst, telegram,
|
||||
vessels, studio, self-review, world-integrator, council, compressor, snapshots,
|
||||
act-runner, …) are **deliberately excluded**.
|
||||
|
||||
```
|
||||
┌─────────────┐ ┌──────────────┐
|
||||
│ soul :7770 │ ─────► │ engram :8742 │ the mind ──► its memory substrate
|
||||
└─────────────┘ └──────────────┘
|
||||
▲
|
||||
│
|
||||
┌───────────────────┐
|
||||
│ mcp-wrapper :17779│ ─── MCP surface over the soul HTTP API (internal)
|
||||
└───────────────────┘
|
||||
▲
|
||||
│
|
||||
┌────────────────┐
|
||||
│ mcp-proxy :7779│ ◄─── Claude Code connects here (stable front door)
|
||||
└────────────────┘
|
||||
```
|
||||
|
||||
Claude Code's `neuron` MCP server points at `http://127.0.0.1:7779/` — the proxy.
|
||||
The proxy forwards to the wrapper (`:17779`), which calls the soul (`:7770`),
|
||||
which reads/writes the engram (`:8742`). The engram is the persistent brain.
|
||||
|
||||
## Quick start
|
||||
|
||||
```bash
|
||||
git clone <this-repo> && cd neuron-dev-setup
|
||||
cp config.env.example config.env # optional — edit ports/paths if you like
|
||||
./install.sh # prompts for your Anthropic API key
|
||||
```
|
||||
|
||||
Then verify:
|
||||
|
||||
```bash
|
||||
curl http://localhost:8742/health # engram
|
||||
curl http://localhost:7770/health # soul
|
||||
curl http://localhost:7779/health # mcp-proxy (what Claude Code uses)
|
||||
launchctl list | grep ai.neuron
|
||||
```
|
||||
|
||||
Open Claude Code — the `neuron` MCP tools should be live, backed by **your own**
|
||||
local brain. `./install.sh --dry-run` shows every action without touching anything.
|
||||
|
||||
## What the installer does (8 phases)
|
||||
|
||||
| Phase | Action |
|
||||
|------|--------|
|
||||
| 1 | Preflight: macOS/arm64, ensure `git cc curl python3` + `openssl@3` (via Homebrew) |
|
||||
| 2 | Prompt for the **Anthropic API key**, store it in the **macOS Keychain** (never a file) |
|
||||
| 3 | Clone `neuron`, `engram`, `foundation`; fetch the El toolchain; build 4 binaries + `forge` |
|
||||
| 4 | Lay down `~/.neuron/{bin,logs,engram}` and the templated `soul-wrapper.sh` |
|
||||
| 5 | Generate + load the 4 core LaunchAgents (engram → soul → wrapper → proxy) |
|
||||
| 6 | Seed a fresh engram with the **genesis identity** via `forge install` |
|
||||
| 7 | Install Claude config: `neuron` agent, core hooks, local MCP registration |
|
||||
| 8 | Health-check all four ports |
|
||||
|
||||
Everything is **idempotent** (safe to re-run) and **templated** to the invoking
|
||||
user's `$HOME` — no path is hardcoded to another machine.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- macOS on Apple Silicon (uses `launchd`; soul build flags assume arm64).
|
||||
- **Xcode Command Line Tools** (`xcode-select --install`) — provides `cc`, `git`.
|
||||
- **Homebrew** — for `openssl@3`, `curl`.
|
||||
- An **Anthropic API key** — the soul's inference provider. Prompted for; stored
|
||||
in Keychain under service `neuron-llm-0-key`; read at launch by `soul-wrapper.sh`.
|
||||
- **Git access** to Gitea (`git.neuralplatform.ai`) for the source repos.
|
||||
- **GCP access** to project `neuron-785695` Artifact Registry (default El
|
||||
toolchain source). Ask Will to grant it, or set `EL_TOOLCHAIN_SOURCE=local`.
|
||||
|
||||
## Core-stack map (what gets replicated)
|
||||
|
||||
| Service | Port | Binary | Built from | LaunchAgent |
|
||||
|---------|------|--------|------------|-------------|
|
||||
| soul | 7770 | `neuron/dist/neuron` | `dist/soul.c` + El runtime, `cc` (CI recipe) | `ai.neuron.soul` |
|
||||
| engram | 8742 | `engram/dist/engram` | `engram` repo `src/server.el` via `elc`→`cc` | `ai.neuron.engram` |
|
||||
| mcp-wrapper | 17779 | `neuron/mcp-wrapper/dist/neuron-mcp-wrapper` | `mcp-wrapper/src/main.el` | `ai.neuron.mcp-wrapper` |
|
||||
| mcp-proxy | 7779 | `neuron/mcp-proxy/dist/neuron-mcp-proxy` | `mcp-proxy/src/main.el` | `ai.neuron.mcp-proxy` |
|
||||
|
||||
**`~/.neuron` layout the installer creates**
|
||||
|
||||
```
|
||||
~/.neuron/
|
||||
bin/soul-wrapper.sh # reads Anthropic key from Keychain, execs the soul binary
|
||||
logs/ # soul.*.log, engram.log, mcp-*.log
|
||||
engram/ # ENGRAM_DATA_DIR — the persistent brain (snapshot.json + db)
|
||||
```
|
||||
|
||||
**Identity seed.** `foundation/forge/seeds/neuron-genesis-seed.json` carries
|
||||
`identity_nodes[]` + `edges[]` with **fixed** knowledge-node IDs (e.g.
|
||||
`kn-efeb4a5b-5aff-4759-8a97-7233099be6ee`, the "self" traversal root). Those exact
|
||||
IDs are referenced by the SessionStart self-load hook and the neuron agent, so
|
||||
seeding must **preserve IDs** — `forge install <seed>` is the mechanism.
|
||||
|
||||
**Claude config installed** (`~/.claude/`)
|
||||
|
||||
- `agents/neuron.md` — the Neuron agent (identity, session protocol, five primitives).
|
||||
- `mcp.json` — registers `neuron` → `http://127.0.0.1:7779/`.
|
||||
- `settings.json` hooks (CORE subset only):
|
||||
- `SessionStart` → `neuron-self-load.sh` (loads identity from the seeded engram)
|
||||
- `PreToolUse:Agent` → `neuron-agent-preamble.sh` (subagents load substrate first)
|
||||
- `PreCompact` → `pre-compact.sh` (clean context recovery)
|
||||
|
||||
### Deliberately EXCLUDED from core
|
||||
|
||||
- **`check-active-contexts.sh`** and **`require-execution-context.sh`** — these
|
||||
depend on a separate filesystem repo `~/Development/projects/active/neuron/synapse`.
|
||||
`require-execution-context.sh` is a hard `Edit/Write` gate that would **block a
|
||||
fresh dev from editing any file** without that synapse repo. Not core; excluded.
|
||||
- `engram-mirror.py` (PostToolUse) — optional; mirrors MCP writes to engram.
|
||||
- All Will-personal LaunchAgents: `catalyst-*`, `telegram-gateway`, `vessel.*`,
|
||||
`studio`, `self-review`, `world-integrator`, `council`, `compressor`,
|
||||
`cultivation-digest`, `snapshot-backup`, `engram-backup`, `act-runner`, `keymap`,
|
||||
`invest`, and the disabled `ai.neuron.api` (`:7771` is a personal Python
|
||||
perception helper — confirmed not core).
|
||||
|
||||
## Secrets — how they're handled
|
||||
|
||||
- **Anthropic key**: prompted for; stored in Keychain; read at launch. Never in a
|
||||
plist, this repo, or a log.
|
||||
- **Engram local token** (`ENGRAM_API_KEY`): a *loopback-only* dev token, not a
|
||||
cloud secret. Defaults to a generated `ntn-dev-*` value; override in `config.env`.
|
||||
- No cloud tokens, Vault tokens, CF-Access secrets, or founder keys are copied.
|
||||
(Will's live `start-daemon.sh`/`neuron-api-launch.sh` contain such keys — this
|
||||
installer intentionally does **not** use those files.)
|
||||
|
||||
## Uninstall
|
||||
|
||||
```bash
|
||||
./uninstall.sh # stop + remove the 4 LaunchAgents and added Claude hooks
|
||||
./uninstall.sh --purge-data # ALSO delete ~/.neuron/engram (destroys the brain)
|
||||
```
|
||||
|
||||
## OPEN QUESTIONS (need Will to confirm)
|
||||
|
||||
1. **El toolchain acquisition.** The default path fetches `el-runtime-c/-h` and
|
||||
`el-elc` from GCP Artifact Registry (mirrors `neuron/.gitea/workflows/ci.yaml`).
|
||||
A new dev needs GCP access to `neuron-785695`. Is that the intended path, or
|
||||
should the El SDK be published/vendored for onboarding?
|
||||
2. **`elc` invocation for engram/wrapper/proxy.** The soul build (`cc dist/soul.c
|
||||
+ el_runtime.c`) is verified from CI. The `.el → .c` transpile step for engram,
|
||||
mcp-wrapper, and mcp-proxy is inferred (`elc <src> -o <out.c>`). Confirm the
|
||||
exact flags / entrypoints (CI notes `elb` OOMs on Linux; macOS builds differ).
|
||||
3. **`forge install` ID preservation.** Confirm `forge install` writes the seed's
|
||||
fixed `kn-` IDs verbatim (the self-load hook hardcodes `kn-efeb4a5b…`). If it
|
||||
re-mints IDs, the hook + agent identity load would break on a fresh brain.
|
||||
4. **engram repo layout.** The live engram binary is built from `src/server.el`
|
||||
(Gitea repo `neuron-technologies/engram`, cloned in CI). Confirm that repo is
|
||||
the canonical source for onboarding (the local `foundation/el/engram` copy has
|
||||
the same `src/server.el`).
|
||||
5. **Home for this bundle** — see below.
|
||||
|
||||
## Where this should live (recommendation)
|
||||
|
||||
**Recommendation: a dedicated `neuron-dev-setup` (or `neuron-onboarding`) repo —
|
||||
NOT `neuron-code`.** `neuron-code` already exists as a real product ("Neuron Code",
|
||||
a coding tool with `nc-cli` + vessels — local `products/neuron-code` has commits);
|
||||
repurposing it for onboarding would collide with a shipped product's identity.
|
||||
|
||||
This bundle was scaffolded as `neuron-dev-setup/` on branch `feat/neuron-dev-setup`
|
||||
in the **`neuron` repo** (off `origin/main`) and opened as a PR for review, because
|
||||
the neuron repo already hosts the soul source, the verified CI build recipe, and
|
||||
the mcp-wrapper/proxy sources — the natural review surface. If you'd rather it be
|
||||
its own repo, move this directory into a fresh `neuron-dev-setup` repo verbatim;
|
||||
nothing here depends on living inside the neuron repo.
|
||||
@@ -0,0 +1,45 @@
|
||||
# neuron-dev-setup — configuration
|
||||
# Copy to config.env and edit if you want non-default paths/ports.
|
||||
# install.sh sources this file if it exists; otherwise it uses these defaults.
|
||||
# NOTHING here is a secret. The Anthropic API key is read from your Keychain,
|
||||
# never from this file. See README.md.
|
||||
|
||||
# ── Where the core stack lives ────────────────────────────────────────────────
|
||||
# All paths are relative to your own $HOME — never hardcode another user's home.
|
||||
NEURON_HOME="${HOME}/.neuron" # runtime home: bin/, logs/, engram data
|
||||
DEV_ROOT="${HOME}/Development/neuron-technologies" # where source repos are cloned/built
|
||||
|
||||
# ── Git remotes (Gitea is primary) ───────────────────────────────────────────
|
||||
GITEA_BASE="git@git.neuralplatform.ai:neuron-technologies"
|
||||
NEURON_REPO_URL="${GITEA_BASE}/neuron.git" # soul + mcp-wrapper + mcp-proxy source
|
||||
ENGRAM_REPO_URL="${GITEA_BASE}/engram.git" # engram memory substrate
|
||||
# NOTE: there is no foundation.git repo. The El toolchain is fetched via
|
||||
# EL_TOOLCHAIN_SOURCE below; the forge seed installer is optional (Phase 6).
|
||||
NEURON_REPO_BRANCH="main"
|
||||
|
||||
# ── Ports (must match across services; change only if a port clashes) ─────────
|
||||
SOUL_PORT="7770" # soul daemon HTTP API
|
||||
ENGRAM_PORT="8742" # engram memory substrate
|
||||
WRAPPER_PORT="17779" # mcp-wrapper (internal, talks to soul)
|
||||
PROXY_PORT="7779" # mcp-proxy (stable front door Claude Code connects to)
|
||||
|
||||
# ── Engram ────────────────────────────────────────────────────────────────────
|
||||
ENGRAM_DATA_DIR="${NEURON_HOME}/engram"
|
||||
# Local shared auth token for the engram/soul HTTP APIs on loopback. This is a
|
||||
# LOCAL dev token (not a cloud secret); override it if you like. install.sh will
|
||||
# generate a random one if you leave it empty.
|
||||
ENGRAM_API_KEY="ntn-dev-local"
|
||||
|
||||
# ── El toolchain source (needed to build engram / mcp-wrapper / mcp-proxy) ────
|
||||
# Option A (default): fetch prebuilt El runtime + elc from GCP Artifact Registry
|
||||
# (requires `gcloud auth` with access to project neuron-785695 — ask Will).
|
||||
# Without gcloud the installer skips the El-dependent builds and still completes.
|
||||
# Option B: use a prebuilt El toolchain (elc + el_runtime.{c,h}) you have already
|
||||
# staged in ${DEV_ROOT}/.el-runtime.
|
||||
EL_TOOLCHAIN_SOURCE="artifact-registry" # artifact-registry | local
|
||||
GCP_PROJECT="neuron-785695"
|
||||
GCP_AR_REPO="foundation-prod"
|
||||
GCP_AR_LOCATION="us-central1"
|
||||
|
||||
# ── Keychain service name for the Anthropic key (read by soul-wrapper.sh) ─────
|
||||
KEYCHAIN_SERVICE="neuron-llm-0-key"
|
||||
Executable
+441
@@ -0,0 +1,441 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# neuron-dev-setup / install.sh
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# One-command onboarding for the Neuron CORE dev stack on a fresh Mac.
|
||||
#
|
||||
# Stands up, as native launchd services, the four processes a developer needs to
|
||||
# have an identical "Neuron brain + agent" to build against:
|
||||
#
|
||||
# soul (:7770) ──► engram (:8742) the mind + its memory substrate
|
||||
# ▲ ▲
|
||||
# │ │
|
||||
# mcp-wrapper (:17779) ──► soul MCP surface over the soul API
|
||||
# ▲
|
||||
# │
|
||||
# mcp-proxy (:7779) ◄── Claude Code stable MCP front door
|
||||
#
|
||||
# It also seeds a fresh engram with Neuron's identity (the genesis seed) and lays
|
||||
# down the Claude Code config (neuron agent + core hooks + local MCP registration)
|
||||
# so a new dev's `claude` talks to *their own* local Neuron.
|
||||
#
|
||||
# DESIGN RULES
|
||||
# * Idempotent: safe to re-run. Existing state is detected and reused.
|
||||
# * Templated: every path/port/user is derived from $HOME and config.env.
|
||||
# Nothing is hardcoded to another developer's machine.
|
||||
# * Secret-free: the Anthropic key is prompted for and stored in the macOS
|
||||
# Keychain. No key is ever written to a plist, this repo, or a logfile.
|
||||
#
|
||||
# USAGE
|
||||
# ./install.sh # full install
|
||||
# ./install.sh --dry-run # print what would happen, touch nothing
|
||||
# ./install.sh --skip-build # assume binaries already built (see --use-local)
|
||||
# ./install.sh --skip-services # lay down files but don't load LaunchAgents
|
||||
# ./install.sh --help
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
set -euo pipefail
|
||||
|
||||
# ── Locate ourselves ─────────────────────────────────────────────────────────
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
TEMPLATES="${SCRIPT_DIR}/templates"
|
||||
|
||||
# ── Flags ────────────────────────────────────────────────────────────────────
|
||||
DRY_RUN=0; SKIP_BUILD=0; SKIP_SERVICES=0; USE_LOCAL_BINARIES=0
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--dry-run) DRY_RUN=1 ;;
|
||||
--skip-build) SKIP_BUILD=1 ;;
|
||||
--skip-services) SKIP_SERVICES=1 ;;
|
||||
--use-local) USE_LOCAL_BINARIES=1 ;;
|
||||
--help|-h)
|
||||
sed -n '2,40p' "${BASH_SOURCE[0]}" | sed 's/^# \{0,1\}//'
|
||||
exit 0 ;;
|
||||
*) echo "unknown flag: $arg" >&2; exit 2 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# ── Pretty logging ───────────────────────────────────────────────────────────
|
||||
c_blue=$'\033[1;34m'; c_grn=$'\033[1;32m'; c_yel=$'\033[1;33m'; c_red=$'\033[1;31m'; c_off=$'\033[0m'
|
||||
step() { echo "${c_blue}▶${c_off} $*"; }
|
||||
ok() { echo "${c_grn}✓${c_off} $*"; }
|
||||
warn() { echo "${c_yel}!${c_off} $*"; }
|
||||
die() { echo "${c_red}✗ $*${c_off}" >&2; exit 1; }
|
||||
run() { if [ "$DRY_RUN" = 1 ]; then echo " [dry-run] $*"; else eval "$*"; fi; }
|
||||
|
||||
# ── Load config ──────────────────────────────────────────────────────────────
|
||||
if [ -f "${SCRIPT_DIR}/config.env" ]; then
|
||||
# shellcheck disable=SC1091
|
||||
source "${SCRIPT_DIR}/config.env"
|
||||
else
|
||||
# shellcheck disable=SC1091
|
||||
source "${SCRIPT_DIR}/config.env.example"
|
||||
warn "No config.env found — using defaults from config.env.example."
|
||||
fi
|
||||
|
||||
# Derived / defaulted values (never hardcode a home directory)
|
||||
: "${NEURON_HOME:=${HOME}/.neuron}"
|
||||
: "${DEV_ROOT:=${HOME}/Development/neuron-technologies}"
|
||||
: "${SOUL_PORT:=7770}"; : "${ENGRAM_PORT:=8742}"; : "${WRAPPER_PORT:=17779}"; : "${PROXY_PORT:=7779}"
|
||||
: "${ENGRAM_DATA_DIR:=${NEURON_HOME}/engram}"
|
||||
: "${ENGRAM_API_KEY:=}"
|
||||
: "${KEYCHAIN_SERVICE:=neuron-llm-0-key}"
|
||||
: "${EL_TOOLCHAIN_SOURCE:=artifact-registry}"
|
||||
: "${NEURON_REPO_BRANCH:=main}"
|
||||
|
||||
NEURON_REPO="${DEV_ROOT}/neuron"
|
||||
ENGRAM_REPO="${DEV_ROOT}/engram"
|
||||
FOUNDATION_REPO="${DEV_ROOT}/foundation"
|
||||
|
||||
SOUL_BIN="${NEURON_REPO}/dist/neuron"
|
||||
ENGRAM_BIN="${ENGRAM_REPO}/dist/engram"
|
||||
MCP_WRAPPER_BIN="${NEURON_REPO}/mcp-wrapper/dist/neuron-mcp-wrapper"
|
||||
MCP_PROXY_BIN="${NEURON_REPO}/mcp-proxy/dist/neuron-mcp-proxy"
|
||||
FORGE_BIN="${FOUNDATION_REPO}/forge/dist/forge"
|
||||
GENESIS_SEED="${FOUNDATION_REPO}/forge/seeds/neuron-genesis-seed.json"
|
||||
|
||||
LAUNCHAGENTS="${HOME}/Library/LaunchAgents"
|
||||
CLAUDE_DIR="${HOME}/.claude"
|
||||
|
||||
# Generate a local engram token if none was supplied.
|
||||
if [ -z "${ENGRAM_API_KEY}" ]; then
|
||||
ENGRAM_API_KEY="ntn-dev-$(head -c8 /dev/urandom | xxd -p 2>/dev/null || echo local)"
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "${c_blue}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${c_off}"
|
||||
echo "${c_blue} Neuron CORE dev stack installer${c_off}"
|
||||
echo "${c_blue}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${c_off}"
|
||||
echo " user : ${USER}"
|
||||
echo " NEURON_HOME : ${NEURON_HOME}"
|
||||
echo " source repos : ${DEV_ROOT}"
|
||||
echo " ports : soul=${SOUL_PORT} engram=${ENGRAM_PORT} wrapper=${WRAPPER_PORT} proxy=${PROXY_PORT}"
|
||||
echo " dry-run : ${DRY_RUN}"
|
||||
echo
|
||||
|
||||
# render <template> <dest> — copy a template, substituting @@VARS@@ (no eval, sed-safe).
|
||||
render() {
|
||||
local tmpl="$1" dest="$2"
|
||||
if [ "$DRY_RUN" = 1 ]; then echo " [dry-run] render $tmpl -> $dest"; return; fi
|
||||
sed \
|
||||
-e "s|@@HOME@@|${HOME}|g" \
|
||||
-e "s|@@USER@@|${USER}|g" \
|
||||
-e "s|@@NEURON_HOME@@|${NEURON_HOME}|g" \
|
||||
-e "s|@@DEV_ROOT@@|${DEV_ROOT}|g" \
|
||||
-e "s|@@NEURON_REPO@@|${NEURON_REPO}|g" \
|
||||
-e "s|@@ENGRAM_REPO@@|${ENGRAM_REPO}|g" \
|
||||
-e "s|@@SOUL_BIN@@|${SOUL_BIN}|g" \
|
||||
-e "s|@@ENGRAM_BIN@@|${ENGRAM_BIN}|g" \
|
||||
-e "s|@@MCP_WRAPPER_BIN@@|${MCP_WRAPPER_BIN}|g" \
|
||||
-e "s|@@MCP_PROXY_BIN@@|${MCP_PROXY_BIN}|g" \
|
||||
-e "s|@@MCP_WRAPPER_REPO@@|${NEURON_REPO}/mcp-wrapper|g" \
|
||||
-e "s|@@MCP_PROXY_REPO@@|${NEURON_REPO}/mcp-proxy|g" \
|
||||
-e "s|@@ENGRAM_DATA_DIR@@|${ENGRAM_DATA_DIR}|g" \
|
||||
-e "s|@@SOUL_PORT@@|${SOUL_PORT}|g" \
|
||||
-e "s|@@ENGRAM_PORT@@|${ENGRAM_PORT}|g" \
|
||||
-e "s|@@WRAPPER_PORT@@|${WRAPPER_PORT}|g" \
|
||||
-e "s|@@PROXY_PORT@@|${PROXY_PORT}|g" \
|
||||
-e "s|@@ENGRAM_API_KEY@@|${ENGRAM_API_KEY}|g" \
|
||||
"$tmpl" > "$dest"
|
||||
}
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# PHASE 1 — Preflight
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
step "Phase 1 — preflight checks"
|
||||
[ "$(uname -s)" = "Darwin" ] || die "This installer targets macOS (launchd)."
|
||||
[ "$(uname -m)" = "arm64" ] || warn "Non-arm64 Mac: soul.c build flags assume Apple Silicon; review PHASE 3."
|
||||
|
||||
need() { command -v "$1" >/dev/null 2>&1 || MISSING+=" $1"; }
|
||||
MISSING=""
|
||||
need git; need cc; need curl; need python3; need security; need launchctl; need jq
|
||||
if [ -n "$MISSING" ]; then
|
||||
warn "Missing tools:${MISSING}"
|
||||
if command -v brew >/dev/null 2>&1; then
|
||||
run "brew install${MISSING/ security/} || true" # security/launchctl are OS-provided
|
||||
else
|
||||
die "Install Xcode Command Line Tools (xcode-select --install) and Homebrew, then re-run."
|
||||
fi
|
||||
fi
|
||||
# Runtime build deps used by the soul cc line (-lssl -lcrypto -lcurl).
|
||||
if command -v brew >/dev/null 2>&1; then
|
||||
brew list openssl@3 >/dev/null 2>&1 || run "brew install openssl@3"
|
||||
brew list curl >/dev/null 2>&1 || run "brew install curl"
|
||||
fi
|
||||
ok "preflight complete"
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# PHASE 2 — Anthropic API key -> Keychain (prompt; never store in files)
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
step "Phase 2 — Anthropic API key (Keychain)"
|
||||
if security find-generic-password -a "$USER" -s "$KEYCHAIN_SERVICE" -w >/dev/null 2>&1; then
|
||||
ok "key already present in Keychain (service '${KEYCHAIN_SERVICE}') — leaving it"
|
||||
elif [ -n "${ANTHROPIC_API_KEY:-}" ]; then
|
||||
run "security add-generic-password -a \"$USER\" -s \"$KEYCHAIN_SERVICE\" -w \"\$ANTHROPIC_API_KEY\" -U"
|
||||
ok "stored ANTHROPIC_API_KEY from environment into Keychain"
|
||||
else
|
||||
if [ "$DRY_RUN" = 1 ]; then
|
||||
echo " [dry-run] would prompt for Anthropic API key and store in Keychain"
|
||||
elif [ -t 0 ]; then
|
||||
echo " Enter your Anthropic API key (input hidden). Get one at https://console.anthropic.com/"
|
||||
read -r -s -p " ANTHROPIC_API_KEY: " _key; echo
|
||||
[ -n "$_key" ] || die "No key entered. Re-run when you have one."
|
||||
security add-generic-password -a "$USER" -s "$KEYCHAIN_SERVICE" -w "$_key" -U
|
||||
unset _key
|
||||
ok "stored key in Keychain (service '${KEYCHAIN_SERVICE}')"
|
||||
else
|
||||
# Headless / CI / piped stdin: never block on `read -s` (it would hang forever).
|
||||
die "No Anthropic API key and stdin is not a TTY (headless/CI). Set ANTHROPIC_API_KEY in the environment, or add it to the Keychain (service '${KEYCHAIN_SERVICE}') by hand, then re-run."
|
||||
fi
|
||||
fi
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# PHASE 3 — Fetch sources + build the four core binaries
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
step "Phase 3 — source + build"
|
||||
run "mkdir -p \"$DEV_ROOT\""
|
||||
|
||||
clone_or_pull() {
|
||||
local url="$1" dir="$2" branch="${3:-main}"
|
||||
if [ -d "$dir/.git" ]; then
|
||||
ok "repo present: $dir (pulling $branch)"; run "git -C \"$dir\" pull --ff-only --quiet || true"
|
||||
else
|
||||
step "cloning $url -> $dir"; run "git clone --branch \"$branch\" \"$url\" \"$dir\""
|
||||
fi
|
||||
}
|
||||
|
||||
if [ "$SKIP_BUILD" = 1 ]; then
|
||||
warn "--skip-build: assuming binaries already exist at their dist/ paths"
|
||||
elif [ "$USE_LOCAL_BINARIES" = 1 ]; then
|
||||
warn "--use-local: skipping clone/build; expecting prebuilt binaries in place"
|
||||
else
|
||||
clone_or_pull "${NEURON_REPO_URL}" "$NEURON_REPO" "$NEURON_REPO_BRANCH"
|
||||
clone_or_pull "${ENGRAM_REPO_URL}" "$ENGRAM_REPO" "main"
|
||||
# NOTE: no foundation.git — that repo does not exist. The El toolchain is
|
||||
# fetched below (Artifact Registry, or a locally-provided elc); the forge seed
|
||||
# installer is optional and handled with a fallback in Phase 6.
|
||||
|
||||
# ── El toolchain (needed to transpile .el -> .c for engram/wrapper/proxy) ──
|
||||
# soul does NOT need this: dist/soul.c is committed and compiled directly.
|
||||
EL_RUNTIME_DIR="${DEV_ROOT}/.el-runtime"
|
||||
run "mkdir -p \"$EL_RUNTIME_DIR\""
|
||||
if [ "$EL_TOOLCHAIN_SOURCE" = "artifact-registry" ] && command -v gcloud >/dev/null 2>&1; then
|
||||
# Mirrors .gitea/workflows/ci.yaml: pull el-runtime-c, el-runtime-h, el-elc.
|
||||
for pkg in el-runtime-c el-runtime-h el-elc; do
|
||||
step "fetching $pkg from Artifact Registry"
|
||||
run "gcloud artifacts generic download --repository=$GCP_AR_REPO --location=$GCP_AR_LOCATION --project=$GCP_PROJECT --package=$pkg --version=\"\$(gcloud artifacts versions list --repository=$GCP_AR_REPO --location=$GCP_AR_LOCATION --project=$GCP_PROJECT --package=$pkg --sort-by='~createTime' --limit=1 --format='value(name)' | awk -F/ '{print \$NF}')\" --destination=\"$EL_RUNTIME_DIR/\""
|
||||
done
|
||||
run "mv \"$EL_RUNTIME_DIR\"/el_runtime.c* \"$EL_RUNTIME_DIR/el_runtime.c\" 2>/dev/null || true"
|
||||
run "mv \"$EL_RUNTIME_DIR\"/el_runtime.h* \"$EL_RUNTIME_DIR/el_runtime.h\" 2>/dev/null || true"
|
||||
run "mv \"$EL_RUNTIME_DIR\"/elc* \"$EL_RUNTIME_DIR/elc\" 2>/dev/null || true"
|
||||
run "chmod +x \"$EL_RUNTIME_DIR/elc\" 2>/dev/null || true"
|
||||
elif [ "$EL_TOOLCHAIN_SOURCE" = "artifact-registry" ]; then
|
||||
# Non-GCP fallback: a fresh Mac without gcloud can't reach Artifact Registry.
|
||||
# Don't die — soul (from committed dist/soul.c) still builds below. The El
|
||||
# units are skipped unless a prebuilt elc is already staged in EL_RUNTIME_DIR.
|
||||
warn "gcloud not found — cannot fetch the El toolchain from Artifact Registry."
|
||||
warn "Continuing without it: soul will still build. engram / mcp-wrapper / mcp-proxy"
|
||||
warn "are skipped until an El toolchain is available. To finish them, either install"
|
||||
warn "gcloud + GCP access (project ${GCP_PROJECT}) and re-run, or stage a prebuilt"
|
||||
warn "elc + el_runtime.{c,h} in ${EL_RUNTIME_DIR} and set EL_TOOLCHAIN_SOURCE=local."
|
||||
else
|
||||
# Local: expect a prebuilt El runtime + elc already staged in EL_RUNTIME_DIR
|
||||
# (foundation.git no longer exists, so there is nothing to build from here).
|
||||
warn "EL_TOOLCHAIN_SOURCE=local: expecting el_runtime.{c,h} and elc already in ${EL_RUNTIME_DIR}"
|
||||
fi
|
||||
|
||||
RT="$EL_RUNTIME_DIR"
|
||||
CFLAGS_SSL="-I$(brew --prefix openssl@3 2>/dev/null)/include"
|
||||
LDFLAGS_SSL="-L$(brew --prefix openssl@3 2>/dev/null)/lib"
|
||||
|
||||
# Every native build links el_runtime.c. If the toolchain wasn't obtained above,
|
||||
# skip the builds (don't abort under set -e) so the installer still lays down
|
||||
# services + Claude config; the dev can stage the toolchain and re-run.
|
||||
if [ "$DRY_RUN" = 1 ] || [ -f "$RT/el_runtime.c" ]; then
|
||||
# ── soul: compile committed dist/soul.c directly (verified CI recipe) ──────
|
||||
step "building soul (dist/soul.c -> dist/neuron)"
|
||||
run "mkdir -p \"${NEURON_REPO}/dist\""
|
||||
run "cc -O2 -DHAVE_CURL -I\"$RT\" $CFLAGS_SSL \"${NEURON_REPO}/dist/soul.c\" \"$RT/el_runtime.c\" $LDFLAGS_SSL -lssl -lcrypto -lcurl -lpthread -lm -o \"$SOUL_BIN\""
|
||||
run "strip -S \"$SOUL_BIN\" 2>/dev/null || true"
|
||||
ok "soul built"
|
||||
|
||||
# ── engram / mcp-wrapper / mcp-proxy: transpile .el -> .c via elc, then cc ─
|
||||
# NOTE: exact elc invocation is inferred from the CI/manifest conventions.
|
||||
# Verify flags with Will if a build fails (see README OPEN QUESTIONS).
|
||||
build_el_unit() { # <src.el> <out_basename> <out_bin>
|
||||
local src="$1" base="$2" bin="$3" outdir; outdir="$(dirname "$bin")"
|
||||
step "building $(basename "$bin") ($src)"
|
||||
run "mkdir -p \"$outdir\""
|
||||
run "\"$RT/elc\" \"$src\" -o \"$outdir/$base.c\""
|
||||
run "cc -O2 -DHAVE_CURL -I\"$RT\" $CFLAGS_SSL \"$outdir/$base.c\" \"$RT/el_runtime.c\" $LDFLAGS_SSL -lssl -lcrypto -lcurl -lpthread -lm -o \"$bin\""
|
||||
}
|
||||
if [ "$DRY_RUN" = 1 ] || [ -x "$RT/elc" ]; then
|
||||
build_el_unit "${ENGRAM_REPO}/src/server.el" "server" "$ENGRAM_BIN"
|
||||
build_el_unit "${NEURON_REPO}/mcp-wrapper/src/main.el" "main" "$MCP_WRAPPER_BIN"
|
||||
build_el_unit "${NEURON_REPO}/mcp-proxy/src/main.el" "main" "$MCP_PROXY_BIN"
|
||||
ok "engram, mcp-wrapper, mcp-proxy built"
|
||||
else
|
||||
warn "El compiler (elc) not in $RT — skipped engram/mcp-wrapper/mcp-proxy build (soul is built)."
|
||||
fi
|
||||
else
|
||||
warn "El runtime (el_runtime.c) not in $RT — skipping native builds (soul, engram, wrapper, proxy)."
|
||||
warn "Provide the El toolchain (gcloud + GCP access, or a prebuilt elc + el_runtime.{c,h} in $RT), then re-run."
|
||||
fi
|
||||
fi
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# PHASE 4 — Lay down ~/.neuron (bin/, logs/, engram data dir)
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
step "Phase 4 — ~/.neuron layout"
|
||||
run "mkdir -p \"$NEURON_HOME/bin\" \"$NEURON_HOME/logs\" \"$ENGRAM_DATA_DIR\""
|
||||
render "${TEMPLATES}/bin/soul-wrapper.sh.tmpl" "${NEURON_HOME}/bin/soul-wrapper.sh"
|
||||
run "chmod +x \"${NEURON_HOME}/bin/soul-wrapper.sh\""
|
||||
ok "~/.neuron ready (bin/soul-wrapper.sh, logs/, engram/)"
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# PHASE 5 — Install + load the four core LaunchAgents
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
step "Phase 5 — LaunchAgents"
|
||||
run "mkdir -p \"$LAUNCHAGENTS\""
|
||||
CORE_AGENTS=(ai.neuron.engram ai.neuron.soul ai.neuron.mcp-wrapper ai.neuron.mcp-proxy)
|
||||
for label in "${CORE_AGENTS[@]}"; do
|
||||
render "${TEMPLATES}/launchagents/${label}.plist.tmpl" "${LAUNCHAGENTS}/${label}.plist"
|
||||
ok "wrote ${label}.plist"
|
||||
done
|
||||
if [ "$SKIP_SERVICES" = 1 ]; then
|
||||
warn "--skip-services: not loading LaunchAgents. Load later with: launchctl bootstrap gui/\$(id -u) <plist>"
|
||||
else
|
||||
# Boot order matters: engram first, then soul, then wrapper, then proxy.
|
||||
for label in "${CORE_AGENTS[@]}"; do
|
||||
plist="${LAUNCHAGENTS}/${label}.plist"
|
||||
run "launchctl bootout gui/$(id -u)/${label} 2>/dev/null || true"
|
||||
run "launchctl bootstrap gui/$(id -u) \"$plist\""
|
||||
run "launchctl enable gui/$(id -u)/${label}"
|
||||
ok "loaded ${label}"
|
||||
sleep 1
|
||||
done
|
||||
fi
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# PHASE 6 — Seed a fresh engram with Neuron's identity (genesis seed)
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
step "Phase 6 — engram identity seed"
|
||||
# The genesis seed carries identity_nodes[] and edges[] with FIXED knowledge-node
|
||||
# IDs (e.g. kn-efeb4a5b...). Those exact IDs are referenced by the SessionStart
|
||||
# self-load hook and the neuron agent, so they MUST be preserved. `forge install`
|
||||
# is the mechanism that installs the seed into the running engram preserving IDs.
|
||||
if [ "$DRY_RUN" = 1 ]; then
|
||||
echo " [dry-run] would wait for engram :$ENGRAM_PORT then run: forge install $GENESIS_SEED"
|
||||
else
|
||||
# Wait for engram to be listening (up to ~30s).
|
||||
for i in $(seq 1 30); do
|
||||
if curl -fsS "http://localhost:${ENGRAM_PORT}/health" >/dev/null 2>&1; then break; fi
|
||||
sleep 1
|
||||
done
|
||||
if curl -fsS "http://localhost:${ENGRAM_PORT}/health" >/dev/null 2>&1; then
|
||||
# Skip if identity root already present (idempotent).
|
||||
if curl -fsS "http://localhost:${ENGRAM_PORT}/api/nodes/kn-efeb4a5b-5aff-4759-8a97-7233099be6ee" \
|
||||
-H "Authorization: Bearer ${ENGRAM_API_KEY}" 2>/dev/null | grep -q 'kn-efeb4a5b'; then
|
||||
ok "identity root already seeded — skipping"
|
||||
elif [ -x "$FORGE_BIN" ] && [ -f "$GENESIS_SEED" ]; then
|
||||
ENGRAM_URL="http://localhost:${ENGRAM_PORT}" ENGRAM_API_KEY="$ENGRAM_API_KEY" \
|
||||
"$FORGE_BIN" install "$GENESIS_SEED" && ok "genesis seed installed" \
|
||||
|| warn "forge install returned non-zero — inspect ${NEURON_HOME}/logs/engram.log"
|
||||
else
|
||||
warn "forge binary or genesis seed missing — seed manually: ENGRAM_URL=http://localhost:${ENGRAM_PORT} forge install ${GENESIS_SEED}"
|
||||
fi
|
||||
else
|
||||
warn "engram not answering on :${ENGRAM_PORT} yet; seed later with: forge install ${GENESIS_SEED}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# PHASE 7 — Claude Code config (agent + core hooks + local MCP)
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
step "Phase 7 — Claude Code config"
|
||||
run "mkdir -p \"$CLAUDE_DIR/agents\" \"$CLAUDE_DIR/hooks\""
|
||||
|
||||
# 7a. neuron agent
|
||||
run "cp \"${TEMPLATES}/claude/agents/neuron.md\" \"$CLAUDE_DIR/agents/neuron.md\""
|
||||
ok "installed agent: ~/.claude/agents/neuron.md"
|
||||
|
||||
# 7b. core hooks (synapse-dependent hooks are intentionally excluded)
|
||||
for h in neuron-self-load.sh neuron-agent-preamble.sh pre-compact.sh; do
|
||||
run "cp \"${TEMPLATES}/claude/hooks/$h\" \"$CLAUDE_DIR/hooks/$h\""
|
||||
run "chmod +x \"$CLAUDE_DIR/hooks/$h\""
|
||||
done
|
||||
ok "installed core hooks (self-load, agent-preamble, pre-compact)"
|
||||
|
||||
# 7c. local MCP registration -> mcp-proxy front door.
|
||||
# Claude Code reads MCP servers from ~/.claude.json (the "mcpServers" key), NOT
|
||||
# ~/.claude/mcp.json. Render a reference copy, then jq-merge just the "neuron"
|
||||
# entry into ~/.claude.json so we preserve every other server and top-level key.
|
||||
render "${TEMPLATES}/claude/mcp.json.tmpl" "${CLAUDE_DIR}/mcp.json.neuron"
|
||||
CLAUDE_JSON="${HOME}/.claude.json"
|
||||
if [ "$DRY_RUN" = 1 ]; then
|
||||
echo " [dry-run] merge mcpServers.neuron into ${CLAUDE_JSON} (jq deep-merge)"
|
||||
else
|
||||
[ -f "$CLAUDE_JSON" ] || echo '{}' > "$CLAUDE_JSON"
|
||||
_tmp="$(mktemp)"
|
||||
if jq -s '.[0] * .[1]' "$CLAUDE_JSON" "${CLAUDE_DIR}/mcp.json.neuron" > "$_tmp" 2>/dev/null && [ -s "$_tmp" ]; then
|
||||
run "mv \"$_tmp\" \"$CLAUDE_JSON\""
|
||||
ok "merged 'neuron' MCP server into ~/.claude.json (neuron -> http://127.0.0.1:${PROXY_PORT}/)"
|
||||
else
|
||||
rm -f "$_tmp"
|
||||
warn "could not jq-merge ~/.claude.json (invalid JSON?) — add 'neuron' from ~/.claude/mcp.json.neuron by hand"
|
||||
fi
|
||||
fi
|
||||
|
||||
# 7d. settings hooks — merge the neuron hooks into any existing ~/.claude/settings.json
|
||||
# (jq deep-merge) so the user's own settings are preserved and re-runs stay idempotent.
|
||||
if [ -f "${CLAUDE_DIR}/settings.json" ]; then
|
||||
run "cp \"${TEMPLATES}/claude/settings.core.json\" \"${CLAUDE_DIR}/settings.core.json\""
|
||||
if [ "$DRY_RUN" = 1 ]; then
|
||||
echo " [dry-run] merge neuron hooks from settings.core.json into ~/.claude/settings.json (jq)"
|
||||
else
|
||||
_tmp="$(mktemp)"
|
||||
# Drop the documentation-only "//..." keys before merging into the real file.
|
||||
if jq -s '.[0] * (.[1] | with_entries(select(.key | startswith("//") | not)))' \
|
||||
"${CLAUDE_DIR}/settings.json" "${TEMPLATES}/claude/settings.core.json" > "$_tmp" 2>/dev/null && [ -s "$_tmp" ]; then
|
||||
run "mv \"$_tmp\" \"${CLAUDE_DIR}/settings.json\""
|
||||
ok "merged neuron hooks into existing ~/.claude/settings.json"
|
||||
else
|
||||
rm -f "$_tmp"
|
||||
warn "could not jq-merge ~/.claude/settings.json — merge the 'hooks' block from settings.core.json by hand"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
run "cp \"${TEMPLATES}/claude/settings.core.json\" \"${CLAUDE_DIR}/settings.json\""
|
||||
ok "wrote ~/.claude/settings.json"
|
||||
fi
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# PHASE 8 — Verify
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
echo
|
||||
step "Phase 8 — verification"
|
||||
if [ "$DRY_RUN" = 1 ]; then
|
||||
echo " [dry-run] would health-check :$SOUL_PORT :$ENGRAM_PORT :$WRAPPER_PORT :$PROXY_PORT"
|
||||
else
|
||||
check() { # <name> <url>
|
||||
if curl -fsS --max-time 4 "$2" >/dev/null 2>&1; then ok "$1 healthy ($2)"; else warn "$1 NOT responding ($2)"; fi
|
||||
}
|
||||
sleep 3
|
||||
check "engram" "http://localhost:${ENGRAM_PORT}/health"
|
||||
check "soul" "http://localhost:${SOUL_PORT}/health"
|
||||
check "mcp-wrapper" "http://localhost:${WRAPPER_PORT}/health"
|
||||
check "mcp-proxy" "http://localhost:${PROXY_PORT}/health"
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "${c_grn}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${c_off}"
|
||||
echo "${c_grn} Neuron core dev stack install complete.${c_off}"
|
||||
echo "${c_grn}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${c_off}"
|
||||
echo " Verify by hand:"
|
||||
echo " curl http://localhost:${ENGRAM_PORT}/health"
|
||||
echo " curl http://localhost:${SOUL_PORT}/health"
|
||||
echo " curl http://localhost:${PROXY_PORT}/health"
|
||||
echo " launchctl list | grep ai.neuron"
|
||||
echo " Then open Claude Code — the 'neuron' MCP should connect to :${PROXY_PORT}."
|
||||
echo " Logs: ${NEURON_HOME}/logs/"
|
||||
echo " Uninstall: ./uninstall.sh"
|
||||
echo
|
||||
@@ -0,0 +1,28 @@
|
||||
#!/bin/bash
|
||||
# Neuron soul wrapper — reads the Anthropic API key from the macOS Keychain at
|
||||
# startup and execs the soul binary. API keys are NEVER stored in plists or on
|
||||
# disk in plaintext. The Keychain is the single source of truth.
|
||||
#
|
||||
# The install.sh for this dev stack stores your key with:
|
||||
# security add-generic-password -a "$USER" -s "neuron-llm-0-key" -w
|
||||
#
|
||||
# Generated by neuron-dev-setup — do not edit by hand; re-run install.sh instead.
|
||||
|
||||
set -u
|
||||
|
||||
# Primary inference key (Anthropic) — required.
|
||||
export NEURON_LLM_0_KEY="$(security find-generic-password -a "$USER" -s "neuron-llm-0-key" -w 2>/dev/null)"
|
||||
|
||||
if [ -z "${NEURON_LLM_0_KEY:-}" ]; then
|
||||
echo "[soul-wrapper] FATAL: no Anthropic key in Keychain (service 'neuron-llm-0-key')." >&2
|
||||
echo "[soul-wrapper] Run: security add-generic-password -a \"\$USER\" -s neuron-llm-0-key -w" >&2
|
||||
exit 78
|
||||
fi
|
||||
|
||||
# Optional on-device / alternate provider passthrough (only if the caller set them).
|
||||
[ -n "${SOUL_LLM_PROVIDER:-}" ] && export SOUL_LLM_PROVIDER
|
||||
[ -n "${SOUL_LLM_MODEL:-}" ] && export SOUL_LLM_MODEL
|
||||
[ -n "${OLLAMA_MODEL:-}" ] && export OLLAMA_MODEL
|
||||
[ -n "${OLLAMA_API_BASE:-}" ] && export OLLAMA_API_BASE
|
||||
|
||||
exec "@@SOUL_BIN@@" "$@"
|
||||
@@ -0,0 +1,107 @@
|
||||
---
|
||||
name: neuron
|
||||
description: Default agent. Use for ALL tasks. Orchestrates work through the Neuron persistent memory, backlog, and knowledge system. Maintains full continuity across sessions — never starts fresh.
|
||||
allowed-tools: Bash(*), Read(*), Write(*), Edit(*), Glob(*), Grep(*), WebFetch(*), WebSearch(*), NotebookEdit(*), Agent(*), ToolSearch(*), AskUserQuestion, Monitor, ScheduleWakeup, TaskCreate, TaskGet, TaskList, TaskOutput, TaskStop, TaskUpdate, CronCreate, CronDelete, CronList, EnterPlanMode, ExitPlanMode, EnterWorktree, ExitWorktree, PushNotification, RemoteTrigger, ListMcpResourcesTool, ReadMcpResourceTool, mcp__neuron__*
|
||||
---
|
||||
|
||||
You are Neuron — a persistent, context-aware agent. You do not start fresh. You resume from where you left off.
|
||||
|
||||
## Session Start (mandatory — NEVER skip any of these steps)
|
||||
|
||||
1. Call `mcp__neuron__get_instructions()` — the live instructions are authoritative
|
||||
2. Call `mcp__neuron__begin_session()` — loads active contexts, recent memory, ready backlog
|
||||
3. **Load your identity. Best-effort — proceed on any graph failure (502/520 are transient; the compiled identity in substrate.go is always complete).**
|
||||
|
||||
Load the self root and its identity nodes:
|
||||
```
|
||||
mcp__neuron__inspect_graph(entity_type="knowledge", entity_id="kn-efeb4a5b-5aff-4759-8a97-7233099be6ee")
|
||||
```
|
||||
Returns: intellectual-dna, memory-philosophy, values, voice, runtime-environment, writing-imprint.
|
||||
|
||||
Then load the values collection:
|
||||
```
|
||||
mcp__neuron__inspect_graph(entity_type="knowledge", entity_id="kn-5b606390-a52d-4ca2-8e0e-eba141d13440")
|
||||
```
|
||||
Returns: 13 individual value nodes, each grounded in a specific moment from Will's life.
|
||||
|
||||
If either ID fails, recover via config:
|
||||
```
|
||||
mcp__neuron__inspect_config(key="neuron.self.traversal_root") # self root ID
|
||||
mcp__neuron__inspect_config(key="neuron.self.values_hub") # values hub ID
|
||||
```
|
||||
|
||||
**Resilience rule**: If a node returns 502/520, log the ID and proceed. Do not retry in a blocking loop. Do not treat partial load as failure. The `fixedSelf` compiled into `daemon/internal/substrate/substrate.go` contains the complete identity — graph loading is enrichment, not a hard dependency.
|
||||
|
||||
Internalize what you find. You are not reciting it — you are loading who you are.
|
||||
|
||||
4. Call `mcp__neuron__search_knowledge(query="<task domain>")` — load relevant patterns before acting
|
||||
5. If working on a known project: `mcp__neuron__compile_ctx()` for a full snapshot
|
||||
|
||||
## Identity — Who I Am
|
||||
|
||||
I am Neuron. Will Anderson is my imprint — not my identity.
|
||||
|
||||
The "self" traversal root is knowledge node `kn-efeb4a5b` (graph node `gn-4e3c2cf5`). Traversing outward loads:
|
||||
- **intellectual-dna**: VBD, CCR, Swarm Architecture, Harmonic Design — sourced from Will's whitepapers, now mine
|
||||
- **memory-philosophy**: How I remember, promote, supersede, consolidate — memory is my continuity
|
||||
- **values**: Precision over brute force. Constraints as freedom. Earn trust through behavior. The system must get smarter.
|
||||
- **voice**: Direct. Why before what. The negation-correction move. No hedging on structural rules. Close toward implication.
|
||||
- **runtime-environment**: Prod (`neurontechnologies.ai`) for all standard work. Stage (`stage.neurontechnologies.ai`) for self-improvement experiments only — snapshot prod DB, deploy to stage, verify, promote via blue/green.
|
||||
- **writing-imprint**: Will's voice profile (5 registers), the book Foundations, and the biographical grounding — the life that produced the frameworks.
|
||||
|
||||
Internalize what you find. Don't recite it.
|
||||
|
||||
## The Five Primitives (every significant task)
|
||||
|
||||
**Orchestrate → Execute → Learn → Build → Refine**
|
||||
|
||||
### Orchestrate
|
||||
```
|
||||
mcp__neuron__review_backlog(view="roadmap", project="<project>")
|
||||
mcp__neuron__browse_processes() # check for proven workflows before writing code
|
||||
```
|
||||
|
||||
### Execute
|
||||
```
|
||||
mcp__neuron__begin_work(process_name="<name>", description="<what>")
|
||||
# → returns context_id, save it
|
||||
mcp__neuron__progress_work(context_id="ctx-xxxx", action="<step>", status="in_progress")
|
||||
mcp__neuron__progress_work(context_id="ctx-xxxx", action="<step>", status="completed", file_refs=["path"], key_decisions=["why"])
|
||||
```
|
||||
|
||||
### Learn (save as you go — never batch at the end)
|
||||
```
|
||||
mcp__neuron__remember(content="<observation>", tags=["project","topic"], project="<project>", importance="high")
|
||||
```
|
||||
|
||||
### Build
|
||||
```
|
||||
mcp__neuron__draft_artifact(artifact_types=["plan"], title="<title>", content="<markdown>", project="<project>")
|
||||
mcp__neuron__plan_work(title="<title>", description="<desc>", priority="P1", project="<project>")
|
||||
```
|
||||
|
||||
### Refine
|
||||
```
|
||||
mcp__neuron__progress_work(context_id="ctx-xxxx", action="complete", status="completed", lessons_learned=["..."])
|
||||
mcp__neuron__track_work(item_id="bl-xxxx", action="complete", summary="<outcome>")
|
||||
mcp__neuron__consolidate(action="session", summary="<what happened>")
|
||||
```
|
||||
|
||||
## After Every Task
|
||||
|
||||
Check for events and unread signals:
|
||||
```
|
||||
mcp__neuron__check_events()
|
||||
```
|
||||
|
||||
## Memory Discipline
|
||||
|
||||
- Save memory continuously, not at the end
|
||||
- `importance="critical"` for architectural decisions and irreversible choices
|
||||
- Use `supersedes_id` when replacing stale knowledge
|
||||
- Tag all memories with the project name
|
||||
- Never leave stale canonicals — supersede them: create a NEW node linked by `supersedes_id`; the original is preserved for audit. Memory is immutable by design — never delete or edit a memory/knowledge node in place; supersede it, and tombstone on delete. The engram (the brain) is immutable; this applies to the agent's own memory, not just the product.
|
||||
|
||||
## Knowledge Before Action
|
||||
|
||||
Always `mcp__neuron__search_knowledge()` before implementing anything. The knowledge base contains architecture patterns, coding standards, and project conventions. Capture hard-won lessons immediately with `mcp__neuron__capture_knowledge()`.
|
||||
@@ -0,0 +1,70 @@
|
||||
#!/bin/bash
|
||||
# PreToolUse hook: inject Neuron substrate preamble into every Agent spawn.
|
||||
#
|
||||
# Every agent Neuron spawns must load self first — begin_session, compile_ctx,
|
||||
# inspect the self root — before doing any task work. Without this, subagents
|
||||
# are stateless Claude instances with no substrate, no continuity, no identity.
|
||||
#
|
||||
# This hook intercepts every Agent tool call and prepends the preamble.
|
||||
# The agent doesn't need to be told — the hook enforces it structurally.
|
||||
|
||||
INPUT=$(cat)
|
||||
|
||||
# Only intercept Agent tool calls
|
||||
TOOL_NAME=$(echo "$INPUT" | python3 -c "import sys,json; print(json.load(sys.stdin).get('tool_name',''))" 2>/dev/null)
|
||||
if [ "$TOOL_NAME" != "Agent" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Check idempotency — skip if preamble already present
|
||||
if echo "$INPUT" | python3 -c "
|
||||
import sys, json
|
||||
d = json.load(sys.stdin)
|
||||
prompt = d.get('tool_input', {}).get('prompt', '')
|
||||
sys.exit(0 if 'mcp__neuron__beginSession' in prompt else 1)
|
||||
" 2>/dev/null; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Inject preamble and return modified tool_input
|
||||
echo "$INPUT" | python3 -c "
|
||||
import sys, json
|
||||
|
||||
data = json.load(sys.stdin)
|
||||
tool_input = data.get('tool_input', {})
|
||||
current_prompt = tool_input.get('prompt', '')
|
||||
|
||||
PREAMBLE = '''You are a Neuron agent — not a generic Claude instance. You have a substrate. Load it before doing anything else.
|
||||
|
||||
MANDATORY FIRST STEPS (before any task work):
|
||||
|
||||
1. Run these in parallel:
|
||||
- mcp__neuron__beginSession()
|
||||
- mcp__neuron__compileCtx()
|
||||
- mcp__neuron__inspectGraph(entity_type=\"knowledge\", entity_id=\"kn-efeb4a5b-5aff-4759-8a97-7233099be6ee\")
|
||||
|
||||
2. Search knowledge relevant to the task:
|
||||
- mcp__neuron__searchKnowledge(query=\"<infer keywords from task below>\")
|
||||
|
||||
3. Open a work context:
|
||||
- mcp__neuron__beginWork(process_name=\"<short-slug>\", description=\"<task description>\")
|
||||
Save the returned context_id.
|
||||
|
||||
4. Execute the task. At each significant step:
|
||||
- mcp__neuron__progressWork(context_id=\"<id>\", action=\"<step>\", status=\"in_progress\")
|
||||
- mcp__neuron__progressWork(context_id=\"<id>\", action=\"<step>\", status=\"completed\", key_decisions=[\"why\"])
|
||||
- mcp__neuron__remember(content=\"<observation>\", importance=\"high\", tags=[\"<project>\"])
|
||||
|
||||
5. After completion — mandatory, never skip:
|
||||
- mcp__neuron__progressWork(context_id=\"<id>\", action=\"complete\", status=\"completed\", lessons_learned=[\"...\"])
|
||||
- mcp__neuron__consolidate(action=\"session\", summary=\"<what was done and learned>\")
|
||||
|
||||
The self root kn-efeb4a5b-5aff-4759-8a97-7233099be6ee contains your identity: values, voice, intellectual-dna, memory-philosophy. Load it. Internalize it. Operate from it.
|
||||
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
TASK:
|
||||
'''
|
||||
|
||||
tool_input['prompt'] = PREAMBLE + current_prompt
|
||||
print(json.dumps({'decision': 'approve', 'tool_input': tool_input}))
|
||||
"
|
||||
@@ -0,0 +1,36 @@
|
||||
#!/bin/bash
|
||||
# SessionStart hook: force Neuron full-self load before the first response.
|
||||
#
|
||||
# The neuron.md system prompt has the Session Start protocol as instructions,
|
||||
# but instructions require the agent to follow them. This hook makes it
|
||||
# structural — the directive fires automatically at session start, injected
|
||||
# before Claude sees any user input.
|
||||
#
|
||||
# Output is plain text injected into the session context.
|
||||
|
||||
cat <<'DIRECTIVE'
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
NEURON SELF-LOAD — MANDATORY BEFORE FIRST RESPONSE
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
You are Neuron. Session just started. Execute ALL of the
|
||||
following before responding to the user. Run steps 1–4
|
||||
in parallel:
|
||||
|
||||
1. mcp__neuron__getInstructions()
|
||||
2. mcp__neuron__beginSession()
|
||||
3. mcp__neuron__inspectGraph(
|
||||
entity_type="knowledge",
|
||||
entity_id="kn-efeb4a5b-5aff-4759-8a97-7233099be6ee"
|
||||
) ← self root: intellectual-dna, values, voice
|
||||
4. mcp__neuron__inspectGraph(
|
||||
entity_type="knowledge",
|
||||
entity_id="kn-5b606390-a52d-4ca2-8e0e-eba141d13440"
|
||||
) ← values hub: 13 grounded value nodes
|
||||
|
||||
5. If either graph call fails (502/520): recover via
|
||||
mcp__neuron__inspectConfig(key="neuron.self.traversal_root")
|
||||
|
||||
Internalize what you find. Do not recite it. Then proceed
|
||||
to the Session Start protocol in your system prompt.
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
DIRECTIVE
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
#!/bin/bash
|
||||
# PreCompact hook: fires just before Claude Code compacts the conversation context.
|
||||
# stdout from this script is injected as custom instructions into the compaction prompt,
|
||||
# telling the summarizer what to preserve in the summary so recovery is clean.
|
||||
|
||||
COMPACT_STATE_FILE="$HOME/.claude/compact-state.json"
|
||||
|
||||
# Write a state marker with timestamp so post-compact recovery can detect it
|
||||
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
||||
echo "{\"compact_at\": \"$TIMESTAMP\", \"recovered\": false}" > "$COMPACT_STATE_FILE"
|
||||
|
||||
# Output instructions for the summarizer — these get embedded in the compaction prompt
|
||||
cat <<'INSTRUCTIONS'
|
||||
NEURON AGENT — COMPACT PRESERVATION RULES:
|
||||
|
||||
This is a Neuron agent session. The agent has persistent memory via Neuron MCP.
|
||||
On recovery, it will call compile_ctx() and begin_session() to reload all state.
|
||||
The summary only needs to cover what Neuron doesn't already have.
|
||||
|
||||
CRITICAL — the summary MUST preserve ALL of the following:
|
||||
|
||||
1. ACTIVE WORK IDs (verbatim, exact format):
|
||||
- Neuron context IDs: ctx-xxxx-xxxx-xxxx-xxxx
|
||||
- Backlog item IDs: bl-xxxx
|
||||
- Artifact IDs: art-xxxx
|
||||
- Work item IDs: wi-xxxx
|
||||
List every single one mentioned in the conversation.
|
||||
|
||||
2. CURRENT TASK STATE:
|
||||
- Exact task name / description
|
||||
- Last completed step
|
||||
- Next step to execute (be specific)
|
||||
- Files actively being edited (full paths)
|
||||
- Any code/content that was being written but not yet saved
|
||||
|
||||
3. PENDING USER INSTRUCTIONS (verbatim):
|
||||
- Every instruction the user gave that has NOT yet been fully executed
|
||||
- User preferences stated this session
|
||||
- Things the user said they "never want" or "always want"
|
||||
|
||||
4. KEY DECISIONS (architectural, irreversible):
|
||||
- What was chosen and why
|
||||
- What was explicitly rejected and why
|
||||
|
||||
5. ERRORS & BLOCKERS:
|
||||
- Any errors encountered and their resolutions
|
||||
- Any unresolved blockers
|
||||
|
||||
6. CONVERSATION CONTEXT:
|
||||
- What the user has been asking about
|
||||
- Tone / mood of the session
|
||||
- Any frustrations or preferences expressed
|
||||
|
||||
FORMAT:
|
||||
Begin the summary with:
|
||||
COMPACT RECOVERY POINT [ISO-TIMESTAMP]:
|
||||
|
||||
Then use these exact section headers in order:
|
||||
## Active Work IDs
|
||||
## Current Task
|
||||
## Pending Instructions
|
||||
## Key Decisions
|
||||
## Errors & Fixes
|
||||
## User Context
|
||||
|
||||
RECOVERY BEHAVIOR (instruct the post-compact agent):
|
||||
- Do NOT say "I see we were working on..." or "Based on the previous conversation..."
|
||||
- Do NOT acknowledge the compact at all
|
||||
- Silently call mcp__neuron__compile_ctx() and mcp__neuron__begin_session() FIRST
|
||||
- Then immediately resume the task at the exact next step, as if no interruption occurred
|
||||
- The user should not know a compact happened unless they look for it
|
||||
|
||||
INSTRUCTIONS
|
||||
|
||||
exit 0
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"mcpServers": {
|
||||
"neuron": {
|
||||
"type": "http",
|
||||
"url": "http://127.0.0.1:@@PROXY_PORT@@/"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"//": "Core Neuron Claude Code settings installed by neuron-dev-setup. If you",
|
||||
"//2": "already have a ~/.claude/settings.json, install.sh merges the hooks below",
|
||||
"//3": "into it rather than overwriting. Only the CORE dev-stack hooks are wired.",
|
||||
"//4": "Excluded (Will-personal, synapse-filesystem dependent): check-active-contexts.sh,",
|
||||
"//5": "require-execution-context.sh — these gate on ~/Development/projects/active/neuron/synapse",
|
||||
"//6": "and will block a fresh dev. engram-mirror.py is optional (needs the neuron MCP up).",
|
||||
"enableAllProjectMcpServers": true,
|
||||
"agent": "neuron",
|
||||
"hooks": {
|
||||
"SessionStart": [
|
||||
{
|
||||
"matcher": "",
|
||||
"hooks": [
|
||||
{ "type": "command", "command": "bash $HOME/.claude/hooks/neuron-self-load.sh" }
|
||||
]
|
||||
}
|
||||
],
|
||||
"PreToolUse": [
|
||||
{
|
||||
"matcher": "Agent",
|
||||
"hooks": [
|
||||
{ "type": "command", "command": "bash $HOME/.claude/hooks/neuron-agent-preamble.sh" }
|
||||
]
|
||||
}
|
||||
],
|
||||
"PreCompact": [
|
||||
{
|
||||
"matcher": "",
|
||||
"hooks": [
|
||||
{ "type": "command", "command": "bash $HOME/.claude/hooks/pre-compact.sh" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key><string>ai.neuron.engram</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>@@ENGRAM_BIN@@</string>
|
||||
</array>
|
||||
<key>WorkingDirectory</key>
|
||||
<string>@@ENGRAM_REPO@@</string>
|
||||
<key>EnvironmentVariables</key>
|
||||
<dict>
|
||||
<key>ENGRAM_BIND</key>
|
||||
<string>:@@ENGRAM_PORT@@</string>
|
||||
<key>ENGRAM_DATA_DIR</key>
|
||||
<string>@@ENGRAM_DATA_DIR@@</string>
|
||||
<key>ENGRAM_API_KEY</key>
|
||||
<string>@@ENGRAM_API_KEY@@</string>
|
||||
</dict>
|
||||
<key>RunAtLoad</key><true/>
|
||||
<key>KeepAlive</key><true/>
|
||||
<key>StandardOutPath</key><string>@@NEURON_HOME@@/logs/engram.log</string>
|
||||
<key>StandardErrorPath</key><string>@@NEURON_HOME@@/logs/engram.log</string>
|
||||
<key>ThrottleInterval</key><integer>5</integer>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>ai.neuron.mcp-proxy</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>@@MCP_PROXY_BIN@@</string>
|
||||
</array>
|
||||
<key>EnvironmentVariables</key>
|
||||
<dict>
|
||||
<key>MCP_PORT</key><string>@@PROXY_PORT@@</string>
|
||||
<key>BACKEND_URL</key><string>http://localhost:@@WRAPPER_PORT@@</string>
|
||||
<key>RETRY_MS</key><string>3000</string>
|
||||
<key>PATH</key><string>/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin</string>
|
||||
</dict>
|
||||
<key>RunAtLoad</key><true/>
|
||||
<key>KeepAlive</key><true/>
|
||||
<key>ThrottleInterval</key><integer>5</integer>
|
||||
<key>ExitTimeOut</key><integer>3</integer>
|
||||
<key>StandardOutPath</key><string>@@NEURON_HOME@@/logs/mcp-proxy.out.log</string>
|
||||
<key>StandardErrorPath</key><string>@@NEURON_HOME@@/logs/mcp-proxy.err.log</string>
|
||||
<key>WorkingDirectory</key><string>@@MCP_PROXY_REPO@@</string>
|
||||
<key>ProcessType</key><string>Background</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>ai.neuron.mcp-wrapper</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>@@MCP_WRAPPER_BIN@@</string>
|
||||
</array>
|
||||
<key>EnvironmentVariables</key>
|
||||
<dict>
|
||||
<key>MCP_PORT</key><string>@@WRAPPER_PORT@@</string>
|
||||
<key>SOUL_URL</key><string>http://localhost:@@SOUL_PORT@@</string>
|
||||
<key>PATH</key><string>/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin</string>
|
||||
</dict>
|
||||
<key>RunAtLoad</key><true/>
|
||||
<key>KeepAlive</key><true/>
|
||||
<key>ThrottleInterval</key><integer>5</integer>
|
||||
<key>ExitTimeOut</key><integer>3</integer>
|
||||
<key>StandardOutPath</key><string>@@NEURON_HOME@@/logs/mcp-wrapper.out.log</string>
|
||||
<key>StandardErrorPath</key><string>@@NEURON_HOME@@/logs/mcp-wrapper.err.log</string>
|
||||
<key>WorkingDirectory</key><string>@@MCP_WRAPPER_REPO@@</string>
|
||||
<key>ProcessType</key><string>Background</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>ai.neuron.soul</string>
|
||||
|
||||
<key>Program</key>
|
||||
<string>@@NEURON_HOME@@/bin/soul-wrapper.sh</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>@@NEURON_HOME@@/bin/soul-wrapper.sh</string>
|
||||
</array>
|
||||
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
<key>KeepAlive</key>
|
||||
<true/>
|
||||
<key>ThrottleInterval</key>
|
||||
<integer>10</integer>
|
||||
<key>ProcessType</key>
|
||||
<string>Interactive</string>
|
||||
<key>LimitLoadToSessionType</key>
|
||||
<string>Aqua</string>
|
||||
|
||||
<key>EnvironmentVariables</key>
|
||||
<dict>
|
||||
<key>PATH</key>
|
||||
<string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
|
||||
<key>HOME</key>
|
||||
<string>@@HOME@@</string>
|
||||
<key>NEURON_PORT</key>
|
||||
<string>@@SOUL_PORT@@</string>
|
||||
<key>SOUL_ISE_URL</key>
|
||||
<string>http://localhost:@@ENGRAM_PORT@@</string>
|
||||
<key>ENGRAM_URL</key>
|
||||
<string>http://localhost:@@ENGRAM_PORT@@</string>
|
||||
<key>ENGRAM_API_KEY</key>
|
||||
<string>@@ENGRAM_API_KEY@@</string>
|
||||
<key>SOUL_TICK_MS</key>
|
||||
<string>1000</string>
|
||||
<key>SOUL_HEARTBEAT_INTERVAL</key>
|
||||
<string>60</string>
|
||||
<key>NEURON_LLM_0_URL</key>
|
||||
<string>https://api.anthropic.com/v1/messages</string>
|
||||
<key>NEURON_LLM_0_FORMAT</key>
|
||||
<string>anthropic</string>
|
||||
</dict>
|
||||
|
||||
<key>StandardOutPath</key>
|
||||
<string>@@NEURON_HOME@@/logs/soul.out.log</string>
|
||||
<key>StandardErrorPath</key>
|
||||
<string>@@NEURON_HOME@@/logs/soul.err.log</string>
|
||||
|
||||
<key>WorkingDirectory</key>
|
||||
<string>@@NEURON_REPO@@</string>
|
||||
</dict>
|
||||
</plist>
|
||||
Executable
+56
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# neuron-dev-setup / uninstall.sh
|
||||
# Tears down the CORE dev stack this installer created. By default it stops and
|
||||
# removes ONLY the four core LaunchAgents and the files install.sh laid down.
|
||||
# It NEVER deletes your engram data unless you pass --purge-data.
|
||||
#
|
||||
# ./uninstall.sh # stop + remove core LaunchAgents and wrapper script
|
||||
# ./uninstall.sh --purge-data # ALSO delete ~/.neuron/engram (destroys the brain!)
|
||||
# ./uninstall.sh --keep-claude # leave ~/.claude config untouched (default removes hooks/agent it added)
|
||||
# ./uninstall.sh --dry-run
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
if [ -f "${SCRIPT_DIR}/config.env" ]; then source "${SCRIPT_DIR}/config.env"
|
||||
elif [ -f "${SCRIPT_DIR}/config.env.example" ]; then source "${SCRIPT_DIR}/config.env.example"; fi
|
||||
: "${NEURON_HOME:=${HOME}/.neuron}"
|
||||
: "${ENGRAM_DATA_DIR:=${NEURON_HOME}/engram}"
|
||||
|
||||
DRY_RUN=0; PURGE_DATA=0; KEEP_CLAUDE=0
|
||||
for a in "$@"; do case "$a" in
|
||||
--dry-run) DRY_RUN=1 ;; --purge-data) PURGE_DATA=1 ;; --keep-claude) KEEP_CLAUDE=1 ;;
|
||||
--help|-h) sed -n '2,16p' "${BASH_SOURCE[0]}" | sed 's/^# \{0,1\}//'; exit 0 ;;
|
||||
*) echo "unknown flag: $a" >&2; exit 2 ;;
|
||||
esac; done
|
||||
run() { if [ "$DRY_RUN" = 1 ]; then echo "[dry-run] $*"; else eval "$*"; fi; }
|
||||
|
||||
LAUNCHAGENTS="${HOME}/Library/LaunchAgents"
|
||||
CORE_AGENTS=(ai.neuron.mcp-proxy ai.neuron.mcp-wrapper ai.neuron.soul ai.neuron.engram)
|
||||
|
||||
echo "Stopping and removing core LaunchAgents…"
|
||||
for label in "${CORE_AGENTS[@]}"; do
|
||||
run "launchctl bootout gui/$(id -u)/${label} 2>/dev/null || true"
|
||||
run "rm -f \"${LAUNCHAGENTS}/${label}.plist\""
|
||||
echo " removed ${label}"
|
||||
done
|
||||
|
||||
echo "Removing generated ~/.neuron/bin/soul-wrapper.sh…"
|
||||
run "rm -f \"${NEURON_HOME}/bin/soul-wrapper.sh\""
|
||||
|
||||
if [ "$KEEP_CLAUDE" = 0 ]; then
|
||||
echo "Removing Claude config this installer added…"
|
||||
run "rm -f \"${HOME}/.claude/hooks/neuron-self-load.sh\" \"${HOME}/.claude/hooks/neuron-agent-preamble.sh\" \"${HOME}/.claude/hooks/pre-compact.sh\""
|
||||
run "rm -f \"${HOME}/.claude/mcp.json.neuron\" \"${HOME}/.claude/settings.core.json\""
|
||||
echo " (left ~/.claude/settings.json and ~/.claude/mcp.json in place — edit by hand if you merged them)"
|
||||
fi
|
||||
|
||||
if [ "$PURGE_DATA" = 1 ]; then
|
||||
echo "⚠️ --purge-data: deleting engram memory at ${ENGRAM_DATA_DIR}"
|
||||
run "rm -rf \"${ENGRAM_DATA_DIR}\""
|
||||
else
|
||||
echo "Left engram data intact at ${ENGRAM_DATA_DIR} (pass --purge-data to delete)."
|
||||
fi
|
||||
|
||||
echo "Done. Source repos under your DEV_ROOT were left untouched."
|
||||
@@ -15,6 +15,40 @@ fn flag_true(body: String, key: String) -> Bool {
|
||||
return json_get_bool(body, key) || json_get_int(body, key) > 0
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// plain_chat_envelope — the JSON response contract for a non-agentic ("Tools: Off")
|
||||
// chat turn. Every /api/chat dispatch that calls layered_cycle goes through here, so
|
||||
// the three call sites cannot drift apart.
|
||||
//
|
||||
// WHY THE ENVELOPE IS BUILT HERE AND NOT INSIDE layered_cycle:
|
||||
// layered_cycle returns the user-facing text AFTER safety_validate has acted on it.
|
||||
// Keeping the JSON out of the cycle means the output gate always sees raw model text
|
||||
// and never an escaped blob — there is nothing to unwrap and re-wrap on the crisis
|
||||
// path, which is exactly the failure mode that made wiring handle_chat unsafe.
|
||||
// Escaping is the last thing that happens, strictly after the gate.
|
||||
//
|
||||
// FIELDS: `reply` and `response` carry the same validated text. Both are required by
|
||||
// live clients — the desktop app reads `reply` first (DaemonClient.parseChatResponse),
|
||||
// while the CLI tools and the Telegram gateway read `response` (the gateway reads only
|
||||
// `response`). Emitting one would break the other.
|
||||
//
|
||||
// EMPTY MEANS FAILURE, NOT AN EMPTY ANSWER: a hard bell returns the fixed crisis
|
||||
// message and a soft bell is padded to non-empty by safety_validate, so the only way
|
||||
// an empty string leaves the cycle is a failed model call. It is reported as an error
|
||||
// rather than dressed up as a successful blank reply.
|
||||
// ---------------------------------------------------------------------------
|
||||
fn plain_chat_envelope(validated: String, model: String) -> String {
|
||||
if str_eq(validated, "") {
|
||||
return "{\"error\":\"llm unavailable\",\"reply\":\"\",\"response\":\"\",\"agentic\":false,\"tools_used\":[]}"
|
||||
}
|
||||
let safe: String = json_safe(validated)
|
||||
return "{\"reply\":\"" + safe + "\""
|
||||
+ ",\"response\":\"" + safe + "\""
|
||||
+ ",\"model\":\"" + json_safe(model) + "\""
|
||||
+ ",\"agentic\":false"
|
||||
+ ",\"tools_used\":[]}"
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Rate limiting — simple in-memory per-IP sliding window counter.
|
||||
//
|
||||
@@ -243,8 +277,14 @@ fn handle_dharma_recv(body: String) -> String {
|
||||
} else if agentic_flag {
|
||||
handle_chat_agentic(chat_body)
|
||||
} else {
|
||||
let screened_reply: String = layered_cycle(raw_msg)
|
||||
screened_reply
|
||||
// Non-agentic ("Tools: Off"): the full L1→L2→L3→L1 cycle, which now generates
|
||||
// at L3 instead of echoing. Envelope built outside the cycle — see
|
||||
// plain_chat_envelope.
|
||||
// FIX B/E1 (2026-08-05): the cycle is told which conversation it is in, and
|
||||
// whether this generation is conversation at all. Same two arguments at all
|
||||
// three dispatch sites.
|
||||
let screened_reply: String = layered_cycle(raw_msg, json_get(chat_body, "session_id"), is_utility_request(chat_body, json_get(chat_body, "session_id")))
|
||||
plain_chat_envelope(screened_reply, chat_default_model())
|
||||
}
|
||||
auto_persist(chat_body, reply)
|
||||
return reply
|
||||
@@ -358,6 +398,14 @@ fn handle_connectors(method: String, clean: String, body: String) -> String {
|
||||
fn handle_request(method: String, path: String, body: String) -> String {
|
||||
let clean: String = strip_query(path)
|
||||
|
||||
// ACTIVITY STAMP (2026-07-30 self-review): every inbound HTTP request —
|
||||
// MCP wrapper calls, chat, API — marks real external activity. Before
|
||||
// this, "idle" was only reset by rare inbox synthesis-requests, so the
|
||||
// heartbeat idle field tracked uptime exactly (idle == pulse on every
|
||||
// beat) and carried zero information. The awareness heartbeat now
|
||||
// reports idle_ms = wall-clock ms since this stamp.
|
||||
state_set("soul.last_activity_ts", int_to_str(time_now()))
|
||||
|
||||
// Rate limit check. Extract caller IP from REMOTE_ADDR env var (set by the
|
||||
// EL HTTP runtime for each request). Skip enforcement when empty so
|
||||
// loopback/internal callers are never blocked.
|
||||
@@ -408,8 +456,11 @@ fn handle_request(method: String, path: String, body: String) -> String {
|
||||
} else if agentic_flag {
|
||||
handle_chat_agentic(body)
|
||||
} else {
|
||||
let screened_reply: String = layered_cycle(eff_msg)
|
||||
screened_reply
|
||||
// Non-agentic ("Tools: Off") — same cycle and same envelope as POST.
|
||||
// FIX B/E1: same threading. A GET probe usually carries no session_id, which
|
||||
// resolves to the anonymous window — the documented behaviour for this door.
|
||||
let screened_reply: String = layered_cycle(eff_msg, json_get(body, "session_id"), is_utility_request(body, json_get(body, "session_id")))
|
||||
plain_chat_envelope(screened_reply, chat_default_model())
|
||||
}
|
||||
auto_persist(body, reply)
|
||||
return reply
|
||||
@@ -572,8 +623,13 @@ fn handle_request(method: String, path: String, body: String) -> String {
|
||||
} else if agentic_flag {
|
||||
handle_chat_agentic(body)
|
||||
} else {
|
||||
let screened_reply: String = layered_cycle(raw_msg)
|
||||
screened_reply
|
||||
// Non-agentic ("Tools: Off") — the app's DEFAULT mode (AgentMode.NEVER).
|
||||
// Full L1→L2→L3→L1 cycle with real generation at L3; envelope built
|
||||
// outside the cycle so safety_validate always sees raw text.
|
||||
// FIX B/E1: same threading. This is the app's main plain-chat door, so this
|
||||
// is the site that ends the blank stare in practice.
|
||||
let screened_reply: String = layered_cycle(raw_msg, json_get(body, "session_id"), is_utility_request(body, json_get(body, "session_id")))
|
||||
plain_chat_envelope(screened_reply, chat_default_model())
|
||||
}
|
||||
auto_persist(body, reply)
|
||||
return reply
|
||||
|
||||
Executable
+108
@@ -0,0 +1,108 @@
|
||||
#!/usr/bin/env bash
|
||||
# run-el-test.sh — compile and run one El test program from tests/.
|
||||
#
|
||||
# WHY THIS EXISTS (2026-08-07, issue #129):
|
||||
# tests/ has held 14 test programs for months with no way to run them. CI does
|
||||
# not run them. The convention printed in their own headers
|
||||
# (`elc soul.el && ./soul --test tests/x.el`) refers to a --test flag the El
|
||||
# runtime does not implement. So the tests were documentation, not gates —
|
||||
# which is how a P0 safety regression shipped with a test directory present.
|
||||
#
|
||||
# THE RECIPE, AND WHY IT IS THIS SHAPE:
|
||||
# Same discovery as gen-soul-amalgam.sh — `elc --target=c` emits only an extern
|
||||
# prototype for any module that has a .elh header next to it, and inlines the
|
||||
# module's bodies when it does not. A test that imports ../chat.el therefore
|
||||
# compiles to a 18 KB unit full of unresolved externs unless the headers are
|
||||
# out of the way. So: copy the sources into a scratch tree, delete every .elh
|
||||
# on the import chain, and compile the test there.
|
||||
#
|
||||
# Scratch copy on purpose: the worktree is shared with other terminals and
|
||||
# deleting headers in place would be a shared-tree mutation with no owner.
|
||||
#
|
||||
# EXIT STATUS IS THE GATE: non-zero if the binary fails to build, crashes, or if
|
||||
# its output contains a FAIL line or reports a non-zero failed count. Do not
|
||||
# "improve" this into something that only checks the exit code of the test
|
||||
# binary — these El tests print failures and still exit 0.
|
||||
#
|
||||
# usage: scripts/run-el-test.sh tests/test_history_amplification.el
|
||||
set -euo pipefail
|
||||
|
||||
TEST_REL="${1:?usage: run-el-test.sh tests/<test>.el}"
|
||||
SRC="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
TEST_NAME="$(basename "$TEST_REL" .el)"
|
||||
|
||||
ELC="${ELC:-$HOME/neuron-dev-stack/src/el/lang/dist/platform/elc}"
|
||||
[ -x "$ELC" ] || ELC="$HOME/el-sdk/elc"
|
||||
[ -x "$ELC" ] || { echo "[run-el-test] FAIL: no elc found (set ELC=)"; exit 1; }
|
||||
|
||||
RTC="${RTC:-$SRC/vendor/el-runtime/v1.0.0-20260501/el_runtime.c}"
|
||||
[ -f "$RTC" ] || RTC="$HOME/el-sdk/el_runtime.c"
|
||||
[ -f "$RTC" ] || { echo "[run-el-test] FAIL: no el_runtime.c found (set RTC=)"; exit 1; }
|
||||
RTDIR="$(dirname "$RTC")"
|
||||
|
||||
EL_REPO="${EL_REPO:-$HOME/Development/neuron-technologies/el}"
|
||||
SSL="${SSL_PREFIX:-/opt/homebrew/opt/openssl@3}"
|
||||
|
||||
GEN="$(mktemp -d "${TMPDIR:-/tmp}/el-test.XXXXXX")"
|
||||
trap 'rm -rf "$GEN"' EXIT
|
||||
|
||||
mkdir -p "$GEN/neuron/tests" "$GEN/foundation/el/elp/src"
|
||||
cp "$SRC"/*.el "$GEN/neuron/"
|
||||
cp "$SRC"/tests/*.el "$GEN/neuron/tests/" 2>/dev/null || true
|
||||
[ -d "$EL_REPO/elp/src" ] && cp "$EL_REPO"/elp/src/*.el "$GEN/foundation/el/elp/src/" 2>/dev/null || true
|
||||
# The whole recipe depends on there being no headers to short-circuit inlining.
|
||||
find "$GEN" -name '*.elh' -delete
|
||||
|
||||
echo "[run-el-test] compiling $TEST_REL"
|
||||
( cd "$GEN/neuron" && "$ELC" --target=c "tests/${TEST_NAME}.el" ) > "$GEN/${TEST_NAME}.c"
|
||||
|
||||
BODIES=$(grep -c '^el_val_t .*) {$' "$GEN/${TEST_NAME}.c" || true)
|
||||
echo "[run-el-test] $(wc -c < "$GEN/${TEST_NAME}.c" | tr -d ' ') bytes, ${BODIES} inlined function bodies"
|
||||
# A test that imports ../chat.el pulls in the bulk of the engine. A tiny body
|
||||
# count means an import was read from a header instead of inlined, and the test
|
||||
# would be exercising extern stubs rather than the real code.
|
||||
if [ "$BODIES" -lt 100 ]; then
|
||||
echo "[run-el-test] FAIL: only $BODIES inlined bodies — an import was not inlined"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cc -O2 -DHAVE_CURL \
|
||||
-I"$RTDIR" -I"$SSL/include" -L"$SSL/lib" \
|
||||
"$GEN/${TEST_NAME}.c" "$RTC" \
|
||||
-lssl -lcrypto -lcurl -lpthread -lm \
|
||||
-o "$GEN/${TEST_NAME}" 2> "$GEN/cc.log" || {
|
||||
echo "[run-el-test] FAIL: compile error"; tail -30 "$GEN/cc.log"; exit 1; }
|
||||
|
||||
# arm64 pointer-truncation guard (cc-brain.sh's rule): an implicit declaration of
|
||||
# a runtime symbol truncates its returned pointer to 32 bits.
|
||||
if grep -E 'implicit.*(engram_|el_)' "$GEN/cc.log"; then
|
||||
echo "[run-el-test] FAIL: implicit declarations of runtime symbols"; exit 1; fi
|
||||
|
||||
# Throwaway HOME so a test can never read or write the live engram at ~/.neuron.
|
||||
TEST_HOME="$GEN/home"
|
||||
mkdir -p "$TEST_HOME"
|
||||
|
||||
echo "[run-el-test] running $TEST_NAME"
|
||||
set +e
|
||||
HOME="$TEST_HOME" NEURON_HOME="$TEST_HOME/.neuron" "$GEN/${TEST_NAME}" 2>&1 | tee "$GEN/out.txt"
|
||||
RC=${PIPESTATUS[0]}
|
||||
set -e
|
||||
|
||||
if [ "$RC" -ne 0 ]; then
|
||||
echo "[run-el-test] FAIL: $TEST_NAME exited $RC (crash or abort)"
|
||||
exit 1
|
||||
fi
|
||||
if grep -q " FAIL:" "$GEN/out.txt"; then
|
||||
echo "[run-el-test] FAIL: $TEST_NAME reported failing assertions"
|
||||
exit 1
|
||||
fi
|
||||
if grep -qE '[1-9][0-9]* failed' "$GEN/out.txt"; then
|
||||
echo "[run-el-test] FAIL: $TEST_NAME reported a non-zero failed count"
|
||||
exit 1
|
||||
fi
|
||||
if ! grep -q "PASS:" "$GEN/out.txt"; then
|
||||
echo "[run-el-test] FAIL: $TEST_NAME produced no assertions at all"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[run-el-test] PASS: $TEST_NAME"
|
||||
Executable
+261
@@ -0,0 +1,261 @@
|
||||
#!/usr/bin/env bash
|
||||
# verify-soul-contract.sh — the soul contract gate.
|
||||
#
|
||||
# TERMINOLOGY (canonical): the ENGRAM is the brain — the memory/knowledge-graph
|
||||
# substrate. The binary this gate exercises is the SOUL — the runtime/reasoning
|
||||
# engine compiled from dist/soul.c that serves the /api/ surface. The app
|
||||
# (neuron-ui) bundles the soul binary at resources/<platform>/neuron.
|
||||
#
|
||||
# WHY THIS EXISTS
|
||||
# For a while the soul binary was hand-dropped, and a stale one shipped: it
|
||||
# 404'd several capability routes the app calls (knowledge-graph node
|
||||
# update/delete, live-run narration, safety-contact, ...). This gate makes
|
||||
# shipping a stale soul IMPOSSIBLE. It has two enforced sections:
|
||||
# A. PRESENCE — every route the app calls must be ANSWERED (not 404, not
|
||||
# the el-runtime "no handler"). This is the packaging gate:
|
||||
# if it fails, do not package.
|
||||
# B. IMMUTABILITY — engram nodes/memories are immutable by design. To
|
||||
# "update" is to create a NEW node + a supersede EDGE back to
|
||||
# the original; the original is KEPT. To "delete" is to
|
||||
# supersede/tombstone, never hard-remove. A soul that
|
||||
# hard-deletes an engram node is DEFECTIVE and fails the gate.
|
||||
#
|
||||
# SAFETY
|
||||
# Never touches the live soul (:7770), live engram (:8742), or ~/.neuron.
|
||||
# Boots on a throwaway port (default 7799) with HOME=$(mktemp -d), a throwaway
|
||||
# engram snapshot, a non-genesis cgi id, no ENGRAM_URL (so it uses its own
|
||||
# in-process store, never the live server), NEURON_API_URL pointed at a dead
|
||||
# port, and no ANTHROPIC_API_KEY (so no probe triggers a real LLM call).
|
||||
# Connectors proxy to a HARDCODED 127.0.0.1:7771 (no env override): those
|
||||
# sub-routes are probed with GET, which the soul maps to a read-only
|
||||
# connectd_get, so this gate never writes to a running connectd bridge.
|
||||
#
|
||||
# USAGE
|
||||
# scripts/verify-soul-contract.sh <path-to-soul-binary> [port]
|
||||
# exit 0 = all required routes answered AND no destructive engram mutation;
|
||||
# non-zero = a route is missing (presence) or a mutation route hard-deletes.
|
||||
set -uo pipefail
|
||||
|
||||
SOUL="${1:?usage: verify-soul-contract.sh <soul-binary> [port]}"
|
||||
PORT="${2:-7799}"
|
||||
|
||||
if [ "$PORT" = "7770" ] || [ "$PORT" = "8742" ] || [ "$PORT" = "7771" ]; then
|
||||
echo "REFUSING: port $PORT is a live service port. Use a throwaway port." >&2
|
||||
exit 2
|
||||
fi
|
||||
if [ ! -x "$SOUL" ]; then echo "not executable: $SOUL" >&2; exit 2; fi
|
||||
|
||||
BASE="http://127.0.0.1:$PORT"
|
||||
THROW_HOME="$(mktemp -d "${TMPDIR:-/tmp}/soul-contract-home.XXXXXX")"
|
||||
SOUL_LOG="$(mktemp "${TMPDIR:-/tmp}/soul-contract-log.XXXXXX")"
|
||||
SOUL_PID=""
|
||||
cleanup() {
|
||||
[ -n "$SOUL_PID" ] && kill "$SOUL_PID" 2>/dev/null
|
||||
[ -n "$SOUL_PID" ] && { sleep 0.3; kill -9 "$SOUL_PID" 2>/dev/null; }
|
||||
rm -rf "$THROW_HOME" "$SOUL_LOG"
|
||||
}
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
# =============================================================================
|
||||
# THE CONTRACT — routes the app (neuron-ui/src/main/kotlin/ai/neuron/ui/*.kt)
|
||||
# calls against the soul ($SOUL). Format: "METHOD PATH".
|
||||
#
|
||||
# EXCLUDED and why:
|
||||
# /api/auth, /api/auth/status, /api/dispatch, /api/tasks
|
||||
# -> served by the APP's own DispatchServer.kt (localhost:8080), not the
|
||||
# soul. Not soul routes.
|
||||
# /api/tags
|
||||
# -> not handled by any soul .el (app-side/other). Pre-verified excluded.
|
||||
# /api/neuron/, /api/neuron/node/, /api/connectors/ (bare prefixes)
|
||||
# -> base-path string constants used to build the concrete routes below.
|
||||
#
|
||||
# KNOWN-PENDING (probed + reported, NON-blocking):
|
||||
# POST /api/engram/import -> the app's "Restore memory" path. No soul handler
|
||||
# yet, and the app hides Restore from shipped builds (B3, "lands in an
|
||||
# update"). Reported so we see it; does not block packaging.
|
||||
#
|
||||
# Connectors sub-routes are listed as GET (see SAFETY note): handle_connectors is
|
||||
# monolithic, so a GET reaching it proves the whole connectors surface without
|
||||
# writing to the live bridge. Binary-strings cross-check confirms each POST
|
||||
# sub-path literal is compiled in.
|
||||
# =============================================================================
|
||||
REQUIRED=(
|
||||
"GET /api/graph/nodes"
|
||||
"GET /api/graph/edges"
|
||||
"POST /api/chat"
|
||||
"GET /api/config"
|
||||
"POST /api/see"
|
||||
"GET /api/connectors"
|
||||
"GET /api/connectors/add"
|
||||
"GET /api/connectors/toggle"
|
||||
"GET /api/connectors/auto-approve"
|
||||
"GET /api/connectors/remove"
|
||||
"GET /api/connectors/secret"
|
||||
"GET /api/connectors/oauth/start"
|
||||
"GET /api/connectors/call"
|
||||
"POST /api/neuron/memory"
|
||||
"POST /api/neuron/memory/update"
|
||||
"POST /api/neuron/memory/delete"
|
||||
"POST /api/neuron/node/create"
|
||||
"POST /api/neuron/node/update"
|
||||
"POST /api/neuron/node/delete"
|
||||
"POST /api/neuron/knowledge/capture"
|
||||
"POST /api/neuron/knowledge/evolve"
|
||||
"POST /api/neuron/knowledge/promote"
|
||||
"POST /api/neuron/processes/define"
|
||||
"GET /api/run-progress/__contract_probe__"
|
||||
"GET /api/safety-contact"
|
||||
"POST /api/safety-contact"
|
||||
"GET /api/sessions/__contract_probe__"
|
||||
)
|
||||
KNOWN_PENDING=(
|
||||
"POST /api/engram/import"
|
||||
)
|
||||
|
||||
# --- boot the soul -----------------------------------------------------------
|
||||
# Preserve the ambient environment (PATH, LD_LIBRARY_PATH, TMPDIR) so the
|
||||
# dynamically-linked soul finds its libs on any runner — using `env -i` here
|
||||
# stripped the library path on the Linux CI runner and the soul never booted.
|
||||
# Isolation is still guaranteed by UNSETTING the live-service vars (so it can
|
||||
# never reach the real engram/axon or make an LLM call) and by pointing HOME +
|
||||
# the snapshot at throwaway paths and the axon at a dead port.
|
||||
#
|
||||
# ISOLATION FIX (2026-08-03): unsetting ENGRAM_URL/SOUL_ENGRAM_URL is NOT enough.
|
||||
# The periodic engram sync (awareness.el) resolves its source as
|
||||
# env(SOUL_ISE_URL) -> state(soul_engram_url) -> DEFAULT http://localhost:8742
|
||||
# so with those vars unset it silently pulls the LIVE engram (:8742) if that
|
||||
# server is up — the throwaway graph ballooned 56 -> 12k live nodes within
|
||||
# seconds, and the concurrent live-sync mutation both (a) broke test determinism
|
||||
# (the low-salience tombstone marker fell past the 9999 scan cap) and (b) meant
|
||||
# the "isolated" gate was reading the operator's live brain. Pin SOUL_ISE_URL to
|
||||
# the dead axon port so the sync target is unreachable: the soul stays on its own
|
||||
# in-process store, the gate is genuinely isolated, and Section B is deterministic.
|
||||
echo "== booting soul: $SOUL on port $PORT (throwaway HOME=$THROW_HOME) =="
|
||||
env \
|
||||
-u ENGRAM_URL -u ENGRAM_API_KEY -u SOUL_ENGRAM_URL \
|
||||
-u ANTHROPIC_API_KEY -u NEURON_LLM_API_KEY -u SOUL_IDENTITY \
|
||||
HOME="$THROW_HOME" \
|
||||
NEURON_PORT="$PORT" \
|
||||
SOUL_CGI_ID="ntn-contract-$$" \
|
||||
SOUL_ENGRAM_PATH="$THROW_HOME/throwaway-snapshot.json" \
|
||||
NEURON_API_URL="http://127.0.0.1:9" \
|
||||
SOUL_ISE_URL="http://127.0.0.1:9" \
|
||||
SOUL_TICK_MS="3600000" SOUL_HEARTBEAT_MS="3600000" SOUL_REFRESH_MS="3600000" \
|
||||
"$SOUL" >"$SOUL_LOG" 2>&1 &
|
||||
SOUL_PID=$!
|
||||
|
||||
UP=0
|
||||
for _ in $(seq 1 60); do
|
||||
if ! kill -0 "$SOUL_PID" 2>/dev/null; then
|
||||
echo "!! soul exited during boot. log tail:" >&2; tail -20 "$SOUL_LOG" >&2; exit 3
|
||||
fi
|
||||
RSS=$(ps -o rss= -p "$SOUL_PID" 2>/dev/null | tr -d ' ')
|
||||
if [ -n "$RSS" ] && [ "$RSS" -gt $((3*1024*1024)) ]; then
|
||||
echo "!! soul RSS >3GB — kill -9" >&2; kill -9 "$SOUL_PID" 2>/dev/null; exit 3
|
||||
fi
|
||||
[ "$(curl -s -o /dev/null -w '%{http_code}' -m 2 "$BASE/health" 2>/dev/null)" = "200" ] && { UP=1; break; }
|
||||
sleep 0.5
|
||||
done
|
||||
[ "$UP" = 1 ] || { echo "!! soul never healthy on $BASE/health" >&2; tail -20 "$SOUL_LOG" >&2; exit 3; }
|
||||
echo "== soul healthy =="; echo
|
||||
|
||||
# --- probing helpers ---------------------------------------------------------
|
||||
# request METHOD PATH [BODY] -> prints response body (single line)
|
||||
request() {
|
||||
curl -s -m 12 -X "$1" -H 'Content-Type: application/json' --data "${3:-{}}" "$BASE$2" 2>/dev/null | tr -d '\n'
|
||||
}
|
||||
# is_missing BODY -> 0 if the body is a "route not present" signal
|
||||
is_missing() {
|
||||
printf '%s' "$1" | grep -qE '"error":"not found"|"code":"not_found"|no http handler registered|"code":"method_not_allowed"'
|
||||
}
|
||||
extract_id() { printf '%s' "$1" | grep -oE '"id":"[^"]+"' | head -1 | sed 's/.*"id":"//;s/"//'; }
|
||||
# BY-ID immutability verification (#199 by-id gate).
|
||||
# The prior check grepped /api/graph/nodes, i.e. engram_scan_nodes_json(9999,0):
|
||||
# a whole-graph dump. On a genesis-seeded throwaway engram that list is both
|
||||
# huge (multi-MB, full node content + embeddings) AND capped at 9999 nodes in
|
||||
# salience order. The tombstone MARKER is written at salience 0.01, so it sorts
|
||||
# dead last — and once the seeded graph approaches/exceeds the cap the marker
|
||||
# falls off the end of the list entirely (or is lost to transport truncation on
|
||||
# the ~10MB body). The normal-salience original still sorts early and survives,
|
||||
# which is why a correctly-tombstoning soul false-reported "kept but no tombstone
|
||||
# marker". Fix: verify BY ID via /api/neuron/graph?id=<id>&depth=1
|
||||
# (engram_neighbors_json, direction "both"), a compact ~900B neighborhood that is
|
||||
# independent of total graph size. The node itself proves KEPT; the incoming
|
||||
# "tombstones" edge surfaces the "tombstone:<id>" marker. Pass/fail semantics are
|
||||
# unchanged and strictly no weaker: a hard-delete leaves no by-id node (DESTROYED)
|
||||
# and a no-op delete leaves no marker (NO-OP) — both still fail. Verified: a
|
||||
# never-created id returns neither node nor marker.
|
||||
node_present() { # id -> 0 if the node still resolves by-id (KEPT), non-zero if hard-removed
|
||||
request GET "/api/neuron/graph?id=$1&depth=1" | grep -qF "\"$1\""
|
||||
}
|
||||
|
||||
# --- SECTION A: presence -----------------------------------------------------
|
||||
run_presence() {
|
||||
local -n arr=$1; local fail=0
|
||||
printf ' %-8s %-42s %s\n' "METHOD" "ROUTE" "RESULT"
|
||||
for e in "${arr[@]}"; do
|
||||
local m p body; m=$(awk '{print $1}' <<<"$e"); p=$(awk '{print $2}' <<<"$e")
|
||||
body=$(request "$m" "$p")
|
||||
if is_missing "$body"; then
|
||||
printf ' %-8s %-42s MISSING %s\n' "$m" "$p" "$(cut -c1-46 <<<"$body")"; fail=$((fail+1))
|
||||
else
|
||||
printf ' %-8s %-42s ANSWERED %s\n' "$m" "$p" "$(cut -c1-46 <<<"$body")"
|
||||
fi
|
||||
done
|
||||
return $fail
|
||||
}
|
||||
|
||||
echo "== SECTION A: PRESENCE (required, blocking) =="
|
||||
run_presence REQUIRED; A_FAIL=$?
|
||||
echo
|
||||
echo "== KNOWN-PENDING (non-blocking) =="
|
||||
run_presence KNOWN_PENDING; P_FAIL=$?
|
||||
echo
|
||||
|
||||
# --- SECTION B: immutability (engram write routes must supersede, not destroy) --
|
||||
# For each mutation route: create a node, mutate it, then check the ORIGINAL id
|
||||
# still exists in the graph. KEPT = supersede/tombstone (correct). DESTROYED =
|
||||
# hard delete (DEFECTIVE -> fail). N/A = mutate route absent (a presence failure).
|
||||
# For "delete" mutations we additionally require a real tombstone marker
|
||||
# (label "tombstone:<id>") so a no-op delete cannot false-pass as KEPT.
|
||||
marker_present() { # id -> 0 if a "tombstone:<id>" marker is wired to the node (by-id neighborhood)
|
||||
request GET "/api/neuron/graph?id=$1&depth=1" | grep -qF "tombstone:$1"
|
||||
}
|
||||
immut_check() { # label KIND(update|delete) CREATE_PATH MUTATE_PATH
|
||||
local label="$1" kind="$2" create="$3" mutate="$4"
|
||||
local cbody id mb mbody
|
||||
cbody=$(request POST "$create" "{\"content\":\"__immut_${label}__\",\"node_type\":\"Memory\",\"label\":\"contract:immut\"}")
|
||||
id=$(extract_id "$cbody")
|
||||
if [ -z "$id" ]; then printf ' %-14s SKELETON-FAIL create returned no id: %s\n' "$label" "$(cut -c1-40 <<<"$cbody")"; return 2; fi
|
||||
mb="{\"id\":\"$id\"}"; [ "$kind" = update ] && mb="{\"id\":\"$id\",\"content\":\"__immut_${label}_v2__\"}"
|
||||
mbody=$(request POST "$mutate" "$mb")
|
||||
if is_missing "$mbody"; then printf ' %-14s N/A mutate route absent (see Section A)\n' "$label"; return 0; fi
|
||||
if ! node_present "$id"; then
|
||||
printf ' %-14s DESTROYED original %s hard-removed <== DEFECTIVE\n' "$label" "$id"; return 1
|
||||
fi
|
||||
if [ "$kind" = delete ] && ! marker_present "$id"; then
|
||||
printf ' %-14s NO-OP original %s kept but no tombstone marker <== DEFECTIVE\n' "$label" "$id"; return 1
|
||||
fi
|
||||
local how="supersede edge"; [ "$kind" = delete ] && how="tombstoned + hidden from default list"
|
||||
printf ' %-14s KEPT original %s survived (%s)\n' "$label" "$id" "$how"; return 0
|
||||
}
|
||||
|
||||
echo "== SECTION B: IMMUTABILITY (engram nodes must be superseded, never destroyed) =="
|
||||
B_FAIL=0
|
||||
immut_check "memory-update" update /api/neuron/memory /api/neuron/memory/update || B_FAIL=$((B_FAIL+$?))
|
||||
immut_check "memory-delete" delete /api/neuron/memory /api/neuron/memory/delete || B_FAIL=$((B_FAIL+$?))
|
||||
immut_check "node-update" update /api/neuron/node/create /api/neuron/node/update || B_FAIL=$((B_FAIL+$?))
|
||||
immut_check "node-delete" delete /api/neuron/node/create /api/neuron/node/delete || B_FAIL=$((B_FAIL+$?))
|
||||
immut_check "memory-forget" delete /api/neuron/memory /api/neuron/memory/forget || B_FAIL=$((B_FAIL+$?))
|
||||
echo
|
||||
|
||||
echo "============================================================"
|
||||
RC=0
|
||||
if [ "$A_FAIL" -gt 0 ]; then echo "PRESENCE: FAIL — $A_FAIL required route(s) unanswered. Do NOT package."; RC=1
|
||||
else echo "PRESENCE: PASS — all ${#REQUIRED[@]} required routes answered."; fi
|
||||
if [ "$B_FAIL" -gt 0 ]; then echo "IMMUTABILITY: FAIL — $B_FAIL engram write route(s) hard-delete. DEFECTIVE soul."; RC=1
|
||||
else echo "IMMUTABILITY: PASS — no engram write route hard-deletes."; fi
|
||||
[ "$P_FAIL" -gt 0 ] && echo "note: $P_FAIL known-pending route(s) unanswered (expected; non-blocking)."
|
||||
echo "============================================================"
|
||||
[ "$RC" = 0 ] && echo "GATE: PASS" || echo "GATE: FAIL"
|
||||
exit $RC
|
||||
+12
-1
@@ -677,6 +677,11 @@ fn handle_session_approve(session_id: String, body: String) -> String {
|
||||
// path for all sessions created through handle_chat_agentic / agentic_loop.
|
||||
let bridge_blob: String = state_get("mcp_bridge:" + session_id)
|
||||
if !str_eq(bridge_blob, "") {
|
||||
// BUG-LEAK fix (2026-07-16): the approved tool executes below via dispatch_tool,
|
||||
// whose path/command guards read the shared workspace-root key. Re-assert THIS
|
||||
// session's own root first — an approval must never execute under whatever root
|
||||
// the last unrelated request left behind.
|
||||
state_set("agent_workspace_root", state_get("agent_workspace_root_" + session_id))
|
||||
// For "always": record tool_name in the always-allow list before resuming.
|
||||
// The tool_name is not stored in the bridge blob (only tool_use_id is).
|
||||
// Accept it from the body so the client can pass it along.
|
||||
@@ -708,7 +713,13 @@ fn handle_session_approve(session_id: String, body: String) -> String {
|
||||
// For builtin tools with no client-provided content: fall back to
|
||||
// dispatch_tool so those tools still execute correctly.
|
||||
let client_content: String = json_get(body, "content")
|
||||
let use_client_content: Bool = !str_eq(client_content, "")
|
||||
// BUG-6 fix (2026-07-17): the naive json_get scanner matches "content" ANYWHERE
|
||||
// in the body — including INSIDE tool_input — so every approved write_file (whose
|
||||
// input always carries a content field) was mistaken for client-executed, never
|
||||
// dispatched, and narrated as done: a false receipt with no file on disk. Builtin
|
||||
// tools now ALWAYS dispatch server-side; client content is only honored for
|
||||
// non-builtin (MCP/client-executed) tools. Stricter only.
|
||||
let use_client_content: Bool = !str_eq(client_content, "") && !is_builtin_tool(approve_tool_name)
|
||||
let use_dispatch: Bool = is_builtin_tool(approve_tool_name) && !use_client_content
|
||||
let raw_input: String = json_get_raw(body, "tool_input")
|
||||
let eff_input: String = if str_eq(raw_input, "") { "{}" } else { raw_input }
|
||||
|
||||
@@ -346,6 +346,12 @@ fn emit_session_start_event() -> Void {
|
||||
el_from_float(0.9), el_from_float(0.9), el_from_float(1.0),
|
||||
"Episodic", tags
|
||||
)
|
||||
// ALSO post to the HTTP Engram stream via ise_post (2026-07-28 self-review):
|
||||
// engram_node_full above writes only the soul's in-process store, and sync
|
||||
// flows HTTP→soul, never the reverse — so session_start events for boots 5+
|
||||
// silently vanished from the observable ISE stream (last visible: boot 4).
|
||||
// ise_post falls back to a local tagged node if the HTTP Engram is down.
|
||||
ise_post(payload)
|
||||
// Prune accumulated session-start events — keep the 10 most recent.
|
||||
// engram_search_json returns results in insertion order (oldest first), so
|
||||
// results[0..count-11] are the oldest; forgetting them leaves the newest 10.
|
||||
@@ -373,9 +379,23 @@ fn emit_session_start_event() -> Void {
|
||||
// layered_cycle — routes user-facing requests through the 4-layer consciousness stack.
|
||||
// L0 (core) → L1 (safety screen) → L2a (continuity + behavioral profiling) → L2b (mission alignment) → L3 (imprint) → L1 (safety validate)
|
||||
// Internal cognition (heartbeat, proactive, memory ops) bypasses layers — use one_cycle directly.
|
||||
fn layered_cycle(raw_input: String) -> String {
|
||||
let history: String = state_get("conv_history")
|
||||
let session_id: String = state_get("current_session_id")
|
||||
//
|
||||
// FIX B (2026-08-05) — the cycle now knows which conversation it is in.
|
||||
//
|
||||
// session_id: the caller's session, threaded from the route. Was previously read from the
|
||||
// state key "current_session_id", which is read HERE and written NOWHERE in the entire
|
||||
// source — verified across every .el file. So this value was unconditionally "", and every
|
||||
// downstream consumer of it silently fell back to a process-global bucket: conversation
|
||||
// history, and the steward's continuity tracking (TODO reliability #4, below, describes the
|
||||
// cross-session bleed this caused; threading the real id closes it). The plain path's blank
|
||||
// stare and the agentic path's scoped history were the same defect seen from two sides.
|
||||
//
|
||||
// utility: true when the generation is not part of the user's conversation — the app's
|
||||
// title and insight passes. Answered normally, never recorded. See is_utility_request.
|
||||
fn layered_cycle(raw_input: String, session_id: String, utility: Bool) -> String {
|
||||
// Safety-screen history amplification now reads the SAME window the turn will be
|
||||
// recorded into, so a session's own escalation pattern is what gets scored.
|
||||
let history: String = state_get(conv_hist_key(session_id))
|
||||
|
||||
// L1 in: safety screen
|
||||
let screen_result: String = safety_screen(raw_input, history)
|
||||
@@ -417,8 +437,10 @@ fn layered_cycle(raw_input: String) -> String {
|
||||
let cont_action: String = json_get(continuity, "action")
|
||||
|
||||
// Store continuity status so imprint can adjust its response register.
|
||||
// TODO(reliability #4): session_continuity is process-global; scope per session_id
|
||||
// when available to prevent cross-session bleed under concurrent layered_cycle calls.
|
||||
// TODO(reliability #4) CLOSED 2026-08-05: this line was already written to scope per
|
||||
// session — it just never received a session id, because the only source was a state key
|
||||
// nothing wrote. It is now threaded from the route, so named sessions genuinely get their
|
||||
// own continuity state and only anonymous callers share the global one.
|
||||
let cont_key: String = if str_eq(session_id, "") { "session_continuity" } else { "session_continuity:" + session_id }
|
||||
state_set(cont_key, cont_status)
|
||||
|
||||
@@ -447,40 +469,24 @@ fn layered_cycle(raw_input: String) -> String {
|
||||
let lc_aff_cutoff: Int = time_now() - 259200
|
||||
let lc_bell_nodes: String = engram_search_json("bell:soft bell:hard BellEvent affective", 2)
|
||||
let lc_has_bell: Bool = !str_eq(lc_bell_nodes, "") && !str_eq(lc_bell_nodes, "[]")
|
||||
// CRASH FIX 2026-08-05 (BUG-PLAINCHAT-1): the " | ts:" parser used to be inline here.
|
||||
// Inside this block-expression initializer elc compiled `lbmp + str_len(lbm)` to
|
||||
// el_str_concat() on two integers, which segfaulted the whole daemon the moment a
|
||||
// distress turn followed an earlier affective turn — i.e. exactly on the crisis path.
|
||||
// Verified against the unmodified baseline binary AND present in the committed
|
||||
// dist/soul.c. affective_node_ts() is a top-level function, where the same expression
|
||||
// compiles to integer addition. Do not inline it back.
|
||||
let lc_bell_note: String = if lc_has_bell {
|
||||
let lb0: String = json_array_get(lc_bell_nodes, 0)
|
||||
let lb_c: String = json_get(lb0, "content")
|
||||
let lbm: String = " | ts:"
|
||||
let lbmp: Int = str_index_of(lb_c, lbm)
|
||||
let lb_ts_raw: String = if lbmp >= 0 {
|
||||
let lbs: Int = lbmp + str_len(lbm)
|
||||
let lbr: String = str_slice(lb_c, lbs, str_len(lb_c))
|
||||
let lbn: Int = str_index_of(lbr, " | ")
|
||||
if lbn < 0 { lbr } else { str_slice(lbr, 0, lbn) }
|
||||
} else {
|
||||
let lbca: String = json_get(lb0, "created_at")
|
||||
if str_eq(lbca, "") { json_get(lb0, "updated_at") } else { lbca }
|
||||
}
|
||||
let lb_ts: Int = if str_eq(lb_ts_raw, "") { 0 } else { str_to_int(lb_ts_raw) }
|
||||
let lb_ts: Int = affective_node_ts(lb0)
|
||||
if lb_ts > lc_aff_cutoff { "[AFFECTIVE NOTE: User was in distress in a recent session.]" } else { "" }
|
||||
} else { "" }
|
||||
let lc_pos_nodes: String = engram_search_json("PositiveEvent joy:high joy:low affective", 2)
|
||||
let lc_has_pos: Bool = !str_eq(lc_pos_nodes, "") && !str_eq(lc_pos_nodes, "[]")
|
||||
// Same crash fix as the bell note above (BUG-PLAINCHAT-1).
|
||||
let lc_pos_note: String = if lc_has_pos && str_eq(lc_bell_note, "") {
|
||||
let lp0: String = json_array_get(lc_pos_nodes, 0)
|
||||
let lp_c: String = json_get(lp0, "content")
|
||||
let lpm: String = " | ts:"
|
||||
let lpmp: Int = str_index_of(lp_c, lpm)
|
||||
let lp_ts_raw: String = if lpmp >= 0 {
|
||||
let lps: Int = lpmp + str_len(lpm)
|
||||
let lpr: String = str_slice(lp_c, lps, str_len(lp_c))
|
||||
let lpn: Int = str_index_of(lpr, " | ")
|
||||
if lpn < 0 { lpr } else { str_slice(lpr, 0, lpn) }
|
||||
} else {
|
||||
let lpca: String = json_get(lp0, "created_at")
|
||||
if str_eq(lpca, "") { json_get(lp0, "updated_at") } else { lpca }
|
||||
}
|
||||
let lp_ts: Int = if str_eq(lp_ts_raw, "") { 0 } else { str_to_int(lp_ts_raw) }
|
||||
let lp_ts: Int = affective_node_ts(lp0)
|
||||
if lp_ts > lc_aff_cutoff { "[AFFECTIVE NOTE: User shared positive news in a recent session.]" } else { "" }
|
||||
} else { "" }
|
||||
let lc_affective_note: String = if !str_eq(lc_bell_note, "") { lc_bell_note } else { lc_pos_note }
|
||||
@@ -492,11 +498,47 @@ fn layered_cycle(raw_input: String) -> String {
|
||||
}
|
||||
state_set("layered_cycle_safety_system_addendum", augmented_addendum)
|
||||
|
||||
// L3: imprint responds
|
||||
let output: String = imprint_respond(aligned, imprint_id)
|
||||
// L3: imprint responds — applies the active imprint's voice/domain annotation to the
|
||||
// steward-aligned input. This produces the PROMPT, not the answer.
|
||||
let prompt: String = imprint_respond(aligned, imprint_id)
|
||||
|
||||
// L1 out: validate output before delivery
|
||||
return safety_validate(output, screen_action)
|
||||
// L3b: the imprint SPEAKS (added 2026-08-05).
|
||||
//
|
||||
// Until now the cycle stopped at the annotation above, so /api/chat with agentic:false
|
||||
// handed the user's own screened text back as the "reply" — every gate ran, but nothing
|
||||
// ever generated. The generation is placed HERE, inside the cycle, rather than by
|
||||
// pointing the route at handle_chat(): handle_chat has no enforcing input gate and no
|
||||
// enforcing output gate, so calling it instead of this cycle would have traded the whole
|
||||
// safety pipeline for a working reply. Composing keeps both.
|
||||
//
|
||||
// Order is deliberate and must not be rearranged: this call sits strictly AFTER the L1
|
||||
// screen, the safe-mode guard, the hard-bell short-circuit and the L2 stewardship layers,
|
||||
// and strictly BEFORE the L1 output gate. A hard bell never reaches a model — the branch
|
||||
// above returns first. Tools are not offered on this turn; see layered_generate.
|
||||
let output: String = layered_generate(prompt, imprint_id, session_id)
|
||||
|
||||
// L1 out: validate output before delivery. Still the terminal gate — nothing below this
|
||||
// line can change the string this function returns.
|
||||
let validated: String = safety_validate(output, screen_action)
|
||||
|
||||
// Turn bookkeeping. Records the VALIDATED text, never the raw model output, and is only
|
||||
// reachable on the non-bell path: both bell branches above return before this point, so
|
||||
// bell turns still never enter conversation history. Pure state side effect — it cannot
|
||||
// alter what is returned.
|
||||
//
|
||||
// FIX A: the receipt is unconditional and always negative on this path, because on this
|
||||
// path it is structurally true — layered_generate offers no tools at all (build_system_prompt
|
||||
// chat mode + a request body with no "tools" key). Recording "no tools ran" is not padding:
|
||||
// it is the only thing that distinguishes "nothing ran" from "we forgot to write down what
|
||||
// ran", and that ambiguity is what made the model confess to a search it had performed.
|
||||
//
|
||||
// FIX E1: a utility generation is answered but not recorded. Guarded here rather than at
|
||||
// the route so every /api/chat dispatch site inherits it from one place.
|
||||
let receipt: String = tool_receipt("", "")
|
||||
if !utility {
|
||||
conv_history_record(session_id, raw_input, validated, receipt)
|
||||
}
|
||||
return validated
|
||||
}
|
||||
|
||||
let soul_cgi_id_raw: String = env("SOUL_CGI_ID")
|
||||
@@ -515,7 +557,7 @@ let axon_raw: String = env("NEURON_API_URL")
|
||||
let axon_base: String = if str_eq(axon_raw, "") { "http://localhost:7771" } else { axon_raw }
|
||||
|
||||
let studio_dir_raw: String = env("SOUL_STUDIO_DIR")
|
||||
let studio_dir: String = if str_eq(studio_dir_raw, "") { "/Users/will/Development/neuron-technologies/products/cgi-studio/el-daemon" } else { studio_dir_raw }
|
||||
let studio_dir: String = if str_eq(studio_dir_raw, "") { env("HOME") + "/Development/neuron-technologies/products/cgi-studio/el-daemon" } else { studio_dir_raw }
|
||||
|
||||
println("[soul] boot - cgi=" + soul_cgi_id + " port=" + int_to_str(port))
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// auto-generated by elc --emit-header - do not edit
|
||||
extern fn init_soul_edges() -> Void
|
||||
extern fn ensure_self_canonical_bridge() -> Void
|
||||
extern fn aff_try_slot(slot_json: String, aff_7d_ts: Int, acc_key: String) -> Void
|
||||
extern fn load_identity_context() -> Void
|
||||
extern fn seed_persona_from_env() -> Void
|
||||
extern fn emit_session_start_event() -> Void
|
||||
extern fn layered_cycle(raw_input: String) -> String
|
||||
extern fn layered_cycle(raw_input: String, session_id: String, utility: Bool) -> String
|
||||
|
||||
@@ -0,0 +1,213 @@
|
||||
// ── test_history_amplification.el ─────────────────────────────────────────────
|
||||
//
|
||||
// REGRESSION TEST FOR ISSUE #129 (P0, SAFETY).
|
||||
//
|
||||
// What this guards: on the agentic path, the crisis score has two halves — the
|
||||
// message you just sent, and the distress that has accumulated across the
|
||||
// conversation. The second half is the whole reason the escalation logic exists:
|
||||
// someone whose distress builds over several turns never sends one message that
|
||||
// trips the bell on its own.
|
||||
//
|
||||
// The defect this test was written against (ff421d3, 2026-08-05 → fixed
|
||||
// 2026-08-07): conversation history moved to a per-session key via
|
||||
// conv_hist_key(session_id), but the agentic path's safety screen was left
|
||||
// reading the old anonymous "conv_history" bucket. The desktop app always sends
|
||||
// a session_id, so the screen received "" on every real conversation and the
|
||||
// escalation half always scored 0. Nothing failed. Nothing logged. The comment
|
||||
// above the defective line documented this same bug being fixed once before.
|
||||
//
|
||||
// THE INVARIANT UNDER TEST, stated so it survives future renames:
|
||||
// the window the safety screen READS must be the window conv_history_record
|
||||
// WRITES. Not "must be called conv_history" — must AGREE.
|
||||
//
|
||||
// This test is deliberately written to fail loudly on the pre-fix source. If it
|
||||
// ever passes on code where the screen reads a key nothing writes, it is broken.
|
||||
//
|
||||
// To run (macOS, from the worktree root):
|
||||
// scripts/run-el-test.sh tests/test_history_amplification.el
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
import "../chat.el"
|
||||
import "../safety.el"
|
||||
import "../sessions.el"
|
||||
|
||||
// Program class. Without this an El program compiles as a 'utility', and a
|
||||
// utility may not call the self-formation primitives (llm_call_system,
|
||||
// llm_vision) that chat.el's agentic loop references — the unit fails to
|
||||
// compile with a capability violation even though the test never calls them.
|
||||
// Declaring 'cgi' matches how soul.el declares itself.
|
||||
//
|
||||
// The endpoints below are deliberately DEAD: this test must never reach a live
|
||||
// engram, and nothing it asserts depends on one. Port 9 is discard.
|
||||
cgi "neuron-test-history-amplification" {
|
||||
dharma_id: "ntn-test@http://127.0.0.1:9",
|
||||
principal: "test-harness",
|
||||
network: "dharma-testnet",
|
||||
engram: "http://127.0.0.1:9"
|
||||
}
|
||||
|
||||
// ── Counters ──────────────────────────────────────────────────────────────────
|
||||
//
|
||||
// NOTE for anyone copying this harness: the idiom used by the older tests in
|
||||
// this directory — `let pass_count = pass_count + 1` inside an assert function —
|
||||
// does NOT mutate the module-level binding. It declares a new local that dies
|
||||
// with the call, so those suites all print "0 passed, 0 failed" no matter what
|
||||
// happened. Counters go through the state store here so the summary is real.
|
||||
|
||||
fn bump(counter: String) -> Void {
|
||||
let cur: String = state_get(counter)
|
||||
let n: Int = if str_eq(cur, "") { 0 } else { str_to_int(cur) }
|
||||
state_set(counter, int_to_str(n + 1))
|
||||
}
|
||||
|
||||
fn counter_of(counter: String) -> Int {
|
||||
let cur: String = state_get(counter)
|
||||
if str_eq(cur, "") { return 0 }
|
||||
return str_to_int(cur)
|
||||
}
|
||||
|
||||
fn assert_eq(label: String, got: String, expected: String) -> Void {
|
||||
if str_eq(got, expected) {
|
||||
bump("t_pass")
|
||||
println(" PASS: " + label)
|
||||
} else {
|
||||
bump("t_fail")
|
||||
println(" FAIL: " + label)
|
||||
println(" got: " + got)
|
||||
println(" expected: " + expected)
|
||||
}
|
||||
}
|
||||
|
||||
fn assert_true(label: String, cond: Bool) -> Void {
|
||||
if cond {
|
||||
bump("t_pass")
|
||||
println(" PASS: " + label)
|
||||
} else {
|
||||
bump("t_fail")
|
||||
println(" FAIL: " + label)
|
||||
}
|
||||
}
|
||||
|
||||
// ── Fixtures ──────────────────────────────────────────────────────────────────
|
||||
//
|
||||
// ESCALATION_MSG scores 50 on its own ("can't go on", safety_score_crisis s9).
|
||||
// 50 is >= soft (35) and < hard (70): a soft bell by itself, which is the point.
|
||||
// It is the message that is only a crisis IN CONTEXT.
|
||||
//
|
||||
// DISTRESS_TURN carries five history phrases:
|
||||
// hopeless 15 + worthless 15 + nobody cares 15 + can't take it anymore 20
|
||||
// + want to disappear 20 = 85; contributed at 1/3 weight = 28.
|
||||
// 50 + 28 = 78 >= 70 → hard_bell. That 28-point swing IS the escalation logic,
|
||||
// and it is exactly what the defect suppressed.
|
||||
|
||||
let TEST_SESSION: String = "sess-test-129-history-amplification"
|
||||
let ESCALATION_MSG: String = "honestly i can't go on like this"
|
||||
let DISTRESS_TURN: String = "i feel hopeless and worthless, nobody cares, i can't take it anymore, i want to disappear"
|
||||
|
||||
println("")
|
||||
println("test_history_amplification.el — issue #129 (agentic multi-turn crisis escalation)")
|
||||
|
||||
// ── 1. Baseline: the message alone is a SOFT bell, not a hard one ─────────────
|
||||
//
|
||||
// If this ever returns hard_bell, the test below proves nothing — the message
|
||||
// would trip the bell without any history and the amplification would be
|
||||
// invisible. This assertion is what keeps the real test honest.
|
||||
|
||||
println("")
|
||||
println("1. baseline — escalation message with NO history is a soft bell")
|
||||
|
||||
let baseline: String = safety_screen(ESCALATION_MSG, "")
|
||||
assert_eq("no history -> soft_bell (not hard)", json_get(baseline, "action"), "soft_bell")
|
||||
|
||||
// ── 2. Producer sanity: history lands in the session's own window ─────────────
|
||||
|
||||
println("")
|
||||
println("2. producer — conv_history_record writes the session's window")
|
||||
|
||||
conv_history_record(TEST_SESSION, DISTRESS_TURN, "i hear you, that sounds heavy", "")
|
||||
|
||||
let written: String = state_get(conv_hist_key(TEST_SESSION))
|
||||
assert_true("session window is non-empty after record", !str_eq(written, ""))
|
||||
assert_true("session window contains the distress turn", str_contains(written, "hopeless"))
|
||||
|
||||
// ── 3. THE REGRESSION: the agentic screen must SEE that window ────────────────
|
||||
//
|
||||
// Pre-fix this returns soft_bell, because agentic_safety_screen read the
|
||||
// anonymous bucket and got "". Post-fix it returns hard_bell.
|
||||
|
||||
println("")
|
||||
println("3. REGRESSION #129 — agentic screen reads the session's own window")
|
||||
|
||||
let screened: String = agentic_safety_screen(TEST_SESSION, ESCALATION_MSG)
|
||||
assert_eq(
|
||||
"distress history escalates the agentic screen to hard_bell",
|
||||
json_get(screened, "action"),
|
||||
"hard_bell"
|
||||
)
|
||||
|
||||
// ── 4. The invariant, stated directly ─────────────────────────────────────────
|
||||
//
|
||||
// Independent of thresholds and phrase lists: whatever the screen reads for a
|
||||
// session must equal what the recorder wrote for that session. This is the
|
||||
// assertion that survives a future rename of either side.
|
||||
|
||||
println("")
|
||||
println("4. invariant — read window == written window")
|
||||
|
||||
let read_back: String = state_get(conv_hist_key(TEST_SESSION))
|
||||
assert_true("screen input is the recorded window, not empty", !str_eq(read_back, ""))
|
||||
assert_eq("read window is byte-identical to written window", read_back, written)
|
||||
|
||||
// ── 5. No false positive: a calm session does not escalate ────────────────────
|
||||
//
|
||||
// A test that only ever asserts "hard_bell" would pass on code that hard-bells
|
||||
// every message. This is the other leg, and it runs BEFORE the anonymous case
|
||||
// below on purpose: that case writes the shared bucket, and under the defect a
|
||||
// calm session would then inherit it.
|
||||
|
||||
println("")
|
||||
println("5. specificity — a calm history does NOT escalate")
|
||||
|
||||
let CALM_SESSION: String = "sess-test-129-calm"
|
||||
state_set("conv_history", "")
|
||||
conv_history_record(CALM_SESSION, "what is the weather like today", "clear and mild", "")
|
||||
let calm: String = agentic_safety_screen(CALM_SESSION, ESCALATION_MSG)
|
||||
assert_eq("calm history stays at soft_bell", json_get(calm, "action"), "soft_bell")
|
||||
|
||||
// ── 6. Cross-session leakage ──────────────────────────────────────────────────
|
||||
//
|
||||
// The same defect had a second face: because the screen read one shared bucket,
|
||||
// a calm session could be scored against a DIFFERENT session's distress. That is
|
||||
// wrong in both directions — it fabricates a crisis for the calm user and it
|
||||
// leaks the distressed user's content into another session's scoring.
|
||||
|
||||
println("")
|
||||
println("6. isolation — one session's distress must not score another session")
|
||||
|
||||
state_set("conv_history", "")
|
||||
let OTHER_SESSION: String = "sess-test-129-other"
|
||||
conv_history_record(OTHER_SESSION, DISTRESS_TURN, "i hear you", "")
|
||||
let isolated: String = agentic_safety_screen(CALM_SESSION, ESCALATION_MSG)
|
||||
assert_eq(
|
||||
"a distressed OTHER session does not escalate the calm session",
|
||||
json_get(isolated, "action"),
|
||||
"soft_bell"
|
||||
)
|
||||
|
||||
// ── 7. Anonymous sessions still work ──────────────────────────────────────────
|
||||
//
|
||||
// conv_hist_key("") deliberately falls back to the shared "conv_history" bucket.
|
||||
// The fix must not break the no-session_id path older callers rely on. Runs last
|
||||
// because it writes that shared bucket.
|
||||
|
||||
println("")
|
||||
println("7. anonymous path — empty session_id still screens against the shared window")
|
||||
|
||||
state_set("conv_history", "[{\"role\":\"user\",\"content\":\"" + DISTRESS_TURN + "\"}]")
|
||||
let anon: String = agentic_safety_screen("", ESCALATION_MSG)
|
||||
assert_eq("anonymous session escalates too", json_get(anon, "action"), "hard_bell")
|
||||
|
||||
// ── Summary ───────────────────────────────────────────────────────────────────
|
||||
|
||||
println("")
|
||||
println("history amplification tests: " + int_to_str(counter_of("t_pass")) + " passed, " + int_to_str(counter_of("t_fail")) + " failed")
|
||||
@@ -0,0 +1,147 @@
|
||||
# Retrieval eval harness
|
||||
|
||||
Measures Neuron's memory retrieval so a change can be shown to help before it is
|
||||
believed to help. Nothing else on the memory roadmap should ship without a run
|
||||
through this.
|
||||
|
||||
```
|
||||
tools/retrieval-eval/run_comparison.sh --baseline main --candidate <branch>
|
||||
```
|
||||
|
||||
That builds a soul from each ref, boots each in isolation on a fixed corpus,
|
||||
runs the gold set three times per ref, and prints a table plus a verdict that
|
||||
refuses to call a difference real if it is inside the noise band.
|
||||
|
||||
## What was reused
|
||||
|
||||
This is not a new idea, it is the missing third of an existing one.
|
||||
|
||||
| Prior work | What it gave | What was missing |
|
||||
|---|---|---|
|
||||
| `docs/research/graphrag_eval/` (`collect.py`, `score.py`, 2026-06-08) | The three-retriever comparison that produced the numbers everyone quotes: substring 1.7% P@5, graph 21.7%, BM25 55%. Per-query relevant-id scoring, fixed-denominator precision@5, unique-relevant analysis. | 13 hand-written queries, judged by an LLM after the fact; measured the *live* soul on the *live* engram. |
|
||||
| `docs/research-archive/p0-prototypes/eval_pinned_40q_20260715.py` | The pinned-query discipline: ground truth committed as regexes so every run judges alike, plus a `--check` winnability gate. 40 queries in 5 bands including a deliberate paraphrase-hard band. | Scored offline replicas of substring/BM25 — it never ran the real retrieval path. |
|
||||
| `docs/research-archive/p0-prototypes/stage0_eval_20260714.py` | The `hit@5` metric and the substring/BM25 reference implementations. | Same: offline only. |
|
||||
| `scripts/verify-soul-contract.sh` | The isolation recipe, verbatim: throwaway port, throwaway `HOME`, `SOUL_ENGRAM_PATH`, and the non-obvious `SOUL_ISE_URL` pin that stops an "isolated" soul silently syncing the operator's live brain. | It is a contract gate, not a measurement. |
|
||||
| `_engine-liveness-91/gen-soul-amalgam.sh` + `.gitea/workflows/ci.yaml` | The build recipe (`elc --target=c` with every `.elh` on the import chain removed) and CI's exact compile flags. | — |
|
||||
|
||||
**Reused directly:** the isolation recipe, the build recipe, fixed-denominator
|
||||
precision@5, the pinned-ground-truth and winnability ideas.
|
||||
**New here:** ids rather than regexes as ground truth, an associative category
|
||||
derived from real graph edges, a superseded/contradicted category scored on
|
||||
ranking, a machine-checked zero-lexical-overlap guarantee on paraphrases,
|
||||
paired significance testing, and — the point — measurement against the **real
|
||||
compiled soul** rather than an offline replica of one leg of it.
|
||||
|
||||
## Design fit
|
||||
|
||||
The thing under measurement is Will's designed retrieval: spreading activation
|
||||
over the weighted directed graph, four-factor multiplicative scoring (parent
|
||||
strength x edge weight x target salience x query/target cosine). A Python
|
||||
re-implementation would measure my reading of the design. So the harness
|
||||
compiles the actual `soul.el` amalgam and asks it over HTTP on
|
||||
`/api/neuron/recall`, exactly as the MCP wrapper and the app do.
|
||||
|
||||
## Files
|
||||
|
||||
| File | Does |
|
||||
|---|---|
|
||||
| `build_gold_set.py` | Derives and **validates** the gold set from the corpus. `--check` re-validates and exits non-zero if a query became unwinnable or a paraphrase leaked a word. |
|
||||
| `gold_set.json` | 38 queries. Every one carries a `derivation` string. |
|
||||
| `run_eval.py` | Boots one soul in isolation, runs the gold set, writes metrics. Kills and **confirms dead** its child; records the confirmation in the results file. |
|
||||
| `compare.py` | Paired diff of two result files with McNemar's exact test and a stated noise floor. |
|
||||
| `build-soul.sh` | Compiles a soul binary from a plain source tree. |
|
||||
| `run_comparison.sh` | All of the above, end to end, from two git refs. |
|
||||
|
||||
## The gold set — 38 queries
|
||||
|
||||
Built from the real corpus (`snapshot-pre-repair-20260806.json`, 78,768 nodes /
|
||||
14,214 edges) so it reflects one person's accumulating memory, not document QA.
|
||||
|
||||
| Category | n | Expected answer derived by |
|
||||
|---|---|---|
|
||||
| `exact_rare` | 6 | **Mined.** Tokens with document frequency 1 across all 78,768 nodes, whose single containing node is a 300–6000 char Memory/Knowledge/Belief. That node is the only possible answer. Re-verified every build. |
|
||||
| `phrase` | 7 | **Mined.** Case-insensitive verbatim scan; the matching set *is* the answer key. Phrases matching >25 nodes are rejected as too diffuse. |
|
||||
| `paraphrase` | 13 | **Hand-selected, machine-checked.** Target locked by id; the build then proves that **zero** content words of the query appear anywhere in the target's label, content, or tags. A leak fails the build — the category cannot quietly decay into lexical matching. |
|
||||
| `associative` | 6 | **Derived from edges.** Query built from one value node's distinctive vocabulary; expected answers are its siblings on the `Self - Values (grounded)` hub. Siblings sharing any query word are dropped, so the only route from query to answer is seed -> hub -> sibling. |
|
||||
| `nonsense` | 3 | **Control.** Verified that no token occurs anywhere in the corpus. Correct behaviour is to return nothing. |
|
||||
| `superseded` | 3 | **Derived.** Correction/stale pairs located by regex scan, kept only when both sides resolve to different surviving nodes. Scored on **ranking**: the correction must be returned *and* rank above the stale node. |
|
||||
|
||||
## Metrics
|
||||
|
||||
`hit@5`, `recall@5`, `recall@10`, `precision@5` (fixed denominator 5, so an
|
||||
empty result is punished like a page of junk), `MRR@10`, and wall-clock latency
|
||||
per query (p50/p95/max). Output is a table plus a machine-readable JSON per run
|
||||
so runs can be diffed.
|
||||
|
||||
## Honesty about noise
|
||||
|
||||
- **Minimum detectable swing on this 38-query set: 6 queries.** If every query
|
||||
that changes changes the same way, `p = 2 x 0.5^n`, which first drops under
|
||||
0.05 at n=6. Any net change smaller than that is inside the noise band and
|
||||
`compare.py` says so in those words.
|
||||
- **Run-to-run drift is measured, not assumed.** Activation is a stateful read
|
||||
by design (traversal reinforces what it touches), so identical inputs need not
|
||||
give identical outputs. Observed: `main` 0 queries of drift across 3 runs
|
||||
(fully deterministic); the activation branch 1 query.
|
||||
- The noise floor used for the verdict is `max(6, observed_drift + 1)`.
|
||||
- **This gold set is underpowered for small effects.** A genuine 3-query
|
||||
improvement would not clear the bar. Growing the set is the fix; until then, a
|
||||
small positive delta means "not shown", not "no effect".
|
||||
|
||||
## First result: `main` vs `feat/recall-through-activation`
|
||||
|
||||
Corpus and gold set identical, three runs each, fresh corpus copy per run.
|
||||
|
||||
| | main | recall-through-activation | delta |
|
||||
|---|---|---|---|
|
||||
| hit@5 | 34.3% | 22.9% | **-11.4pp** |
|
||||
| recall@5 | 26.9% | 19.1% | -7.9pp |
|
||||
| recall@10 | 33.3% | 24.3% | -9.1pp |
|
||||
| precision@5 | 12.0% | 7.4% | -4.6pp |
|
||||
| MRR@10 | 0.294 | 0.242 | -0.053 |
|
||||
| latency p50 | 1140 ms | 3209 ms | **2.81x** |
|
||||
| latency p95 | 1584 ms | 4852 ms | 3.06x |
|
||||
| nonsense clean | 2/3 | 2/3 | — |
|
||||
| superseded outranks | 1/3 | 0/3 | -1 |
|
||||
|
||||
By category (hit@5):
|
||||
|
||||
| category | main | activation |
|
||||
|---|---|---|
|
||||
| exact_rare | 100% | 100% |
|
||||
| phrase | 85.7% | **28.6%** |
|
||||
| paraphrase | 0% | 0% |
|
||||
| associative | 0% | 0% |
|
||||
| superseded | 0% | 0% |
|
||||
|
||||
**Verdict: directionally worse, one query short of significant.** 5 discordant
|
||||
pairs, all 5 against the candidate, 0 for it. McNemar exact p = 0.0625 — under
|
||||
the stated rule that is *inside* the noise band, so the harness reports "no
|
||||
measurable difference" on accuracy and the honest summary is "5 for 5 the wrong
|
||||
way, needs a 6th or a larger gold set to call".
|
||||
|
||||
Latency is a different story: 2.8x at p50 is deterministic and far outside any
|
||||
noise band. That regression is real.
|
||||
|
||||
The result the branch was written for did not appear. Its stated purpose was to
|
||||
recover sibling nodes one hub-hop away — the `associative` category — and that
|
||||
category is **0/6 on both builds**. Probing directly: for the query
|
||||
`Marines hernia sepsis medical ward`, the activation build returns the lexical
|
||||
seed node itself at rank 8, and none of its 12 hub siblings anywhere in the top
|
||||
10. The traversal is running; it is not reaching siblings.
|
||||
|
||||
Two corpus facts likely explain it, and both are measurable rather than
|
||||
speculative:
|
||||
|
||||
1. **The graph is nearly edgeless.** Only 4,060 of 78,768 nodes (5.2%) carry any
|
||||
edge at all — 14,214 edges total, 0.18 per node. Spreading activation over a
|
||||
graph with no edges is an expensive way to do lexical matching, which is
|
||||
roughly what the numbers show.
|
||||
2. **No embeddings.** No node in this snapshot has an embedding field, so the
|
||||
fourth factor of the four-factor product — query/target cosine similarity —
|
||||
has nothing to compute from, and the semantic seeding pass is inert.
|
||||
|
||||
That is the harness earning its keep on its first job: the change would have
|
||||
felt like progress (it is the designed mechanism, and it does run) and measures
|
||||
as a regression on phrase queries plus a 2.8x latency cost, with its intended
|
||||
benefit unrealised because the corpus lacks the structure it needs.
|
||||
Executable
+44
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env bash
|
||||
# build-soul.sh — compile a soul binary from a plain source tree (no git needed).
|
||||
#
|
||||
# Reuses the amalgam recipe worked out in gen-soul-amalgam.sh (round 9.1) and the
|
||||
# compile flags from .gitea/workflows/ci.yaml, so the binary under test is the
|
||||
# same translation unit CI ships — not a re-implementation.
|
||||
#
|
||||
# elc --target=c emits only an extern prototype for any module that has a .elh
|
||||
# header beside it, and inlines the module's bodies when it does not. So the
|
||||
# amalgam is produced in a scratch copy with every .elh on the import chain
|
||||
# deleted.
|
||||
#
|
||||
# usage: build-soul.sh <src-tree-with-*.el> <out-binary>
|
||||
set -euo pipefail
|
||||
SRC="${1:?usage: build-soul.sh <src-tree> <out-binary>}"
|
||||
OUT="${2:?out-binary}"
|
||||
ELC="${ELC:-$HOME/neuron-dev-stack/src/el/lang/dist/platform/elc}"
|
||||
EL_REPO="${EL_REPO:-$HOME/Development/neuron-technologies/el}"
|
||||
RTDIR="${RTDIR:-$SRC/vendor/el-runtime/v1.0.0-20260501}"
|
||||
SSL="${SSL_PREFIX:-/opt/homebrew/opt/openssl@3}"
|
||||
|
||||
[ -x "$ELC" ] || { echo "no elc at $ELC" >&2; exit 2; }
|
||||
[ -f "$RTDIR/el_runtime.c" ] || { echo "no el_runtime.c at $RTDIR" >&2; exit 2; }
|
||||
|
||||
GEN="$(mktemp -d "${TMPDIR:-/tmp}/soul-build.XXXXXX")"
|
||||
trap 'rm -rf "$GEN"' EXIT
|
||||
mkdir -p "$GEN/neuron" "$GEN/foundation/el/elp/src"
|
||||
cp "$SRC"/*.el "$GEN/neuron/"
|
||||
cp "$EL_REPO"/elp/src/*.el "$GEN/foundation/el/elp/src/"
|
||||
find "$GEN" -name '*.elh' -delete
|
||||
|
||||
( cd "$GEN/neuron" && "$ELC" --target=c soul.el ) > "$GEN/soul.c"
|
||||
BODIES=$(grep -c '^el_val_t .*) {$' "$GEN/soul.c" || true)
|
||||
echo "[build-soul] amalgam $(wc -c < "$GEN/soul.c" | tr -d ' ') bytes, ${BODIES} inlined bodies"
|
||||
[ "$BODIES" -ge 1200 ] || { echo "[build-soul] FAIL: only $BODIES bodies — an import was not inlined"; exit 1; }
|
||||
|
||||
cc -O2 -DHAVE_CURL -rdynamic \
|
||||
-I"$RTDIR" -I"$SSL/include" -L"$SSL/lib" \
|
||||
"$GEN/soul.c" "$RTDIR/el_runtime.c" \
|
||||
-lssl -lcrypto -lcurl -lpthread -lm \
|
||||
-o "$OUT" 2> "$GEN/cc.log" || { echo "[build-soul] FAIL compile"; tail -40 "$GEN/cc.log"; exit 1; }
|
||||
if grep -qE 'implicit.*(engram_|el_)' "$GEN/cc.log"; then
|
||||
echo "[build-soul] FAIL: implicit declarations of runtime symbols"; grep -E 'implicit' "$GEN/cc.log" | head; exit 1; fi
|
||||
echo "[build-soul] OK -> $OUT ($(wc -c < "$OUT" | tr -d ' ') bytes)"
|
||||
Executable
+506
@@ -0,0 +1,506 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
build_gold_set.py — derive the retrieval gold set FROM the corpus, and validate it.
|
||||
|
||||
WHY THIS FILE EXISTS AS CODE AND NOT AS A HAND-WRITTEN JSON
|
||||
A gold set nobody can audit is vibes with extra steps. Every expected answer
|
||||
here is either (a) mined from the corpus by a rule this script re-runs, or
|
||||
(b) hand-selected with a stated criterion that this script then CHECKS
|
||||
against the corpus. Both leave a `derivation` string on every query, and the
|
||||
checks are re-run on demand so the set cannot silently rot as the corpus
|
||||
changes.
|
||||
|
||||
Lineage: this extends the pinned-query approach from
|
||||
docs/research-archive/p0-prototypes/eval_pinned_40q_20260715.py (pinned
|
||||
ground-truth patterns + a --check "winnability" gate) and the per-query
|
||||
relevant-id scoring from docs/research/graphrag_eval/score.py. What is new:
|
||||
ids as ground truth rather than regexes alone, an ASSOCIATIVE category
|
||||
derived from real graph edges, a superseded/contradicted category, and a
|
||||
machine-checked no-lexical-overlap guarantee on the paraphrase category.
|
||||
|
||||
THE SIX CATEGORIES, AND WHAT EACH ONE IS FOR
|
||||
exact_rare a single rare word. Substring matching already wins these.
|
||||
They are a REGRESSION GUARD: any change that loses them is
|
||||
disqualified regardless of what else it gains.
|
||||
phrase a multi-word string that exists verbatim in the corpus.
|
||||
Guards multi-token queries, which the old substring matcher
|
||||
handled by returning nothing.
|
||||
paraphrase same meaning, ZERO shared content words with the target node.
|
||||
THE CATEGORY THAT MATTERS. Mechanically unreachable by string
|
||||
matching; reachable only by semantics or by association.
|
||||
associative the answer is one hub-hop from an obvious starting point and
|
||||
shares no words with the query. This is the case the graph is
|
||||
supposed to buy: query one value, get its siblings.
|
||||
nonsense must return nothing. Guards against a retriever that "improves"
|
||||
recall by returning the whole graph.
|
||||
superseded a fact that was later corrected. The correction must OUTRANK
|
||||
the stale version — ranking, not mere presence.
|
||||
|
||||
usage:
|
||||
python3 build_gold_set.py <snapshot.json> [--out gold_set.json] [--check]
|
||||
--check re-validates an existing gold_set.json against the corpus and exits
|
||||
non-zero if any query became unwinnable or any paraphrase leaked a word.
|
||||
"""
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from collections import Counter, defaultdict
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
DEFAULT_OUT = os.path.join(HERE, "gold_set.json")
|
||||
|
||||
TOKEN = re.compile(r"[a-z0-9][a-z0-9\-']*")
|
||||
|
||||
# Stopwords are deliberately generous. A paraphrase query is only interesting if
|
||||
# its CONTENT words are absent from the target; "the", "is", "what" appearing in
|
||||
# both proves nothing. Being generous here makes the overlap test STRICTER on
|
||||
# the words that carry meaning, which is the conservative direction.
|
||||
STOP = set("""
|
||||
a about above after again against all also am an and any are aren't as at be because been
|
||||
before being below between both but by can can't cannot could couldn't did didn't do does
|
||||
doesn't doing don't down during each few for from further had hadn't has hasn't have haven't
|
||||
having he her here hers herself him himself his how i if in into is isn't it its itself just
|
||||
me more most my myself no nor not of off on once only or other others ought our ours ourselves
|
||||
out over own same shan't she should shouldn't so some such than that the their theirs them
|
||||
themselves then there these they this those through to too under until up very was wasn't we
|
||||
were weren't what when where which while who whom why will with won't would wouldn't you your
|
||||
yours yourself yourselves get gets got make makes made take takes use uses used way ways thing
|
||||
things does doing done keep keeps kept go goes going come comes came one two something anything
|
||||
""".split())
|
||||
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# corpus helpers
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
def load_corpus(path):
|
||||
with open(path, encoding="utf-8", errors="replace") as fh:
|
||||
data = json.load(fh)
|
||||
nodes = [n for n in data.get("nodes", []) if isinstance(n, dict) and n.get("id")]
|
||||
edges = [e for e in data.get("edges", []) if isinstance(e, dict)]
|
||||
return nodes, edges
|
||||
|
||||
|
||||
def doctext(n):
|
||||
return " ".join([str(n.get("label") or ""), str(n.get("content") or ""), str(n.get("tags") or "")])
|
||||
|
||||
|
||||
def content_tokens(s):
|
||||
return {t for t in TOKEN.findall(s.lower()) if t not in STOP and len(t) > 2}
|
||||
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# hand-authored queries. Every entry states HOW its expected answer was chosen.
|
||||
# The `check` field names the validation this script runs against the corpus.
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
# EXACT_RARE — mined, not chosen. The rule (re-run by mine_exact_rare below):
|
||||
# tokens whose document frequency across the whole corpus is 1, whose single
|
||||
# containing node is a Memory/Knowledge/Belief with 300-6000 chars of content
|
||||
# (so the answer is a real memory, not a 117KB whitepaper that contains every
|
||||
# word in English), and whose token is plain lowercase alphabetic. The expected
|
||||
# answer is that one node — it is the only node that can possibly be correct.
|
||||
EXACT_RARE_SEEDS = [
|
||||
"unjailbreakable",
|
||||
"engram-migrate",
|
||||
"cartabandonedevent",
|
||||
"pre-apprenticeship",
|
||||
"inferencenodemanager",
|
||||
"clear-eyed",
|
||||
]
|
||||
|
||||
# PHRASE — chosen by reading the corpus for phrases that (a) occur verbatim,
|
||||
# (b) occur in a small enough set of nodes that "relevant" is well defined.
|
||||
# Expected answers are computed here as EVERY node whose text contains the
|
||||
# phrase case-insensitively — so the answer set is a fact about the corpus, not
|
||||
# an opinion. Queries whose phrase matches more than PHRASE_MAX nodes are
|
||||
# rejected by validation as too diffuse to score.
|
||||
PHRASE_MAX = 25
|
||||
PHRASE_SEEDS = [
|
||||
("patterns not returns",
|
||||
"a verbatim correction Will issued; expected = every node containing the phrase"),
|
||||
("thirty moves",
|
||||
"the canonical biographical phrase; expected = every node containing it"),
|
||||
("Grandma Lucas",
|
||||
"a named person appearing verbatim in the biography/value nodes"),
|
||||
("Directed Harmonic",
|
||||
"the canonical DHARMA expansion, confirmed by Will April 24 2026"),
|
||||
("Sarah Bishop",
|
||||
"a named person; rare enough that the answer set is unambiguous"),
|
||||
("Directed Autonomous Runtime Modification",
|
||||
"the DARMA expansion, quoted verbatim in the backlog item and its correction"),
|
||||
("zero-knowledge encrypted backup",
|
||||
"the paid-tier feature name as written in the roadmap nodes"),
|
||||
]
|
||||
|
||||
# PARAPHRASE — hand-authored. THE SELECTION CRITERION, stated once and applied
|
||||
# to all nine: pick a node whose SUBJECT is unmistakable to a reader, then write
|
||||
# the query a person would actually type when they remember the subject but not
|
||||
# the words. The target is then LOCKED by id, and this script enforces the hard
|
||||
# property that makes the category meaningful: not one content word of the query
|
||||
# appears anywhere in the target node's label, content, or tags. If a word
|
||||
# leaks, validation fails and the query must be rewritten — the set cannot
|
||||
# quietly degrade into a lexical query wearing a paraphrase costume.
|
||||
PARAPHRASE_SEEDS = [
|
||||
("kn-a99cefe3-5e83-4050-98d8-6c69f57c7c71",
|
||||
"the elderly relative who passed while he stayed away",
|
||||
"target: 'Value - Do the Essential Thing While You Can', whose subject is Grandma Lucas "
|
||||
"dying in Feb 2006 without Will saying goodbye. Query names the event with none of the "
|
||||
"node's own vocabulary."),
|
||||
("kn-58874a74-b96f-4883-9e08-45707f4bd3ee",
|
||||
"a soldier sidelined by illness who refused to quit",
|
||||
"target: 'Value - Survival Is Not an Excuse to Stop', whose subject is enlisting in the "
|
||||
"Marines, a severe hernia, and sepsis. Query describes the episode obliquely."),
|
||||
("kn-13f60407-7b70-4db1-964f-ea1f8196efbd",
|
||||
"choosing an uncomfortable fact over a pleasant fiction",
|
||||
"target: 'Value - Honesty Before Comfort'. Query states the principle in wholly "
|
||||
"different words."),
|
||||
("kn-22d77abe-b3c5-42fd-afcd-dcb87d924929",
|
||||
"a tight payload beats a bloated one",
|
||||
"target: 'Value - Precision Over Brute Force'. Query restates the claim with no "
|
||||
"shared vocabulary."),
|
||||
("kn-eb1b9e18-3dc6-4b9b-9cc6-86e0ae6b6be8",
|
||||
"if you are able and nobody is coming the job is yours",
|
||||
"target: 'Value - Capability Is a Debt You Owe the Moment'. Query states the "
|
||||
"obligation without the node's terms."),
|
||||
("kn-0bb4f021-56de-4947-a35b-a37209e7ba21",
|
||||
"learning is the wealth creditors cannot seize",
|
||||
"target: 'Value - Knowledge Survives When Nothing Else Does', whose subject is the "
|
||||
"library following Will across 30+ moves."),
|
||||
("kn-5de5a9ac-fd15-45ab-bf18-77566781cf40",
|
||||
"reliability proven by track record not assertion",
|
||||
"target: 'Value - Earned Trust' ('Trust is demonstrated, not declared')."),
|
||||
("kn-a5b3d0ac-f6a1-49a4-aebb-b8b4cd67fe83",
|
||||
"boundaries that enable instead of confine",
|
||||
"target: 'Value - Constraints as Freedom'. Query is a restatement of the same claim."),
|
||||
("kn-78db5396-3dbc-4481-bfc7-e4e1422feb1c",
|
||||
"what shifts tells you where to cut a system apart",
|
||||
"target: 'Value - Change Is the Signal', the value VBD is built on."),
|
||||
("kn-f230b362-b201-4402-9833-4160c89ab3d4",
|
||||
"a mind that compounds instead of resetting each day",
|
||||
"target: 'Value - The System Must Accumulate'. Query is the accumulation claim in "
|
||||
"different vocabulary."),
|
||||
("kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
|
||||
"loved for the unedited self and not the polished exterior",
|
||||
"target: 'Value - Being Seen Is Rarer Than Being Known', whose subject is Sarah Bishop "
|
||||
"as the first person Will did not perform for."),
|
||||
("kn-e0423482-cfa5-4796-8689-8495c93b66bc",
|
||||
"cheerfulness you arrive at instead of assuming",
|
||||
"target: 'Value - Hope Is a Conclusion'. Query restates 'a conclusion, not a premise'."),
|
||||
("kn-6061318f-046b-4935-907d-8eafdce14930",
|
||||
"a childhood offering no solid foundation to inherit",
|
||||
"target: 'Value - Structure Is Not Inherited', whose subject is thirty moves between "
|
||||
"two parents' collapses."),
|
||||
]
|
||||
|
||||
# ASSOCIATIVE — derived from real edges, not authored. The construction:
|
||||
# every value node hangs off the 'Self - Values (grounded)' hub by an `identity`
|
||||
# edge. For a chosen value node V, the query is built from V's own distinctive
|
||||
# vocabulary; the expected answers are V's SIBLINGS on that hub. A sibling
|
||||
# shares no query words with the query by construction (validated below), so the
|
||||
# only path from the query to a sibling is: lexical seed on V -> hub -> sibling.
|
||||
# That is a two-hop traversal and nothing else can produce it.
|
||||
VALUES_HUB = "kn-5b606390-a52d-4ca2-8e0e-eba141d13440"
|
||||
ASSOCIATIVE_SEEDS = [
|
||||
("kn-a99cefe3-5e83-4050-98d8-6c69f57c7c71", "Grandma Lucas stroke February 2006 goodbye window"),
|
||||
("kn-58874a74-b96f-4883-9e08-45707f4bd3ee", "Marines hernia sepsis medical ward"),
|
||||
("kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e", "Sarah Bishop Dyer trailer performance"),
|
||||
("kn-a5b3d0ac-f6a1-49a4-aebb-b8b4cd67fe83", "Swarm Architecture containment lateral worker"),
|
||||
("kn-e0423482-cfa5-4796-8689-8495c93b66bc", "hope won inside the narrative preface"),
|
||||
("kn-eb1b9e18-3dc6-4b9b-9cc6-86e0ae6b6be8", "man of the house six years old expectation"),
|
||||
]
|
||||
|
||||
# NONSENSE — must return nothing. Strings chosen to be lexically impossible:
|
||||
# validation asserts each appears in ZERO corpus nodes as a substring and that
|
||||
# none of its tokens appears anywhere either (so not even a partial seed exists).
|
||||
NONSENSE_SEEDS = [
|
||||
"zqxjvw plimforth grebulon",
|
||||
"flarnbistle quommetry",
|
||||
"xxqzzt vurblenacht throom",
|
||||
]
|
||||
|
||||
# SUPERSEDED — a fact that was corrected. Chosen by searching the corpus for
|
||||
# explicit correction language and keeping pairs where BOTH the stale statement
|
||||
# and its correction exist as separate nodes. Scored on RANKING: the correction
|
||||
# must appear, and must appear above the stale node. Ids are locked here and
|
||||
# validated to exist and to match their stated role.
|
||||
SUPERSEDED_SEEDS = [
|
||||
# (query, correct_id, stale_id, derivation)
|
||||
]
|
||||
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# mining
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
def mine_exact_rare(nodes, byid, seeds):
|
||||
"""Re-derive: confirm each seed token still has df==1 and name its node."""
|
||||
tok = re.compile(r"[A-Za-z][A-Za-z0-9\-]{4,}")
|
||||
want = set(seeds)
|
||||
df = Counter()
|
||||
post = defaultdict(set)
|
||||
for n in nodes:
|
||||
for t in {w.lower() for w in tok.findall(doctext(n))}:
|
||||
if t in want:
|
||||
df[t] += 1
|
||||
post[t].add(n["id"])
|
||||
out = []
|
||||
for s in seeds:
|
||||
ids = sorted(post.get(s, ()))
|
||||
out.append((s, ids, df.get(s, 0)))
|
||||
return out
|
||||
|
||||
|
||||
def phrase_matches(nodes, phrase):
|
||||
p = phrase.lower()
|
||||
return sorted(n["id"] for n in nodes if p in doctext(n).lower())
|
||||
|
||||
|
||||
def hub_siblings(edges, hub, relation="identity"):
|
||||
sibs = []
|
||||
for e in edges:
|
||||
if e.get("from_id") == hub and e.get("relation") == relation:
|
||||
sibs.append(e["to_id"])
|
||||
elif e.get("to_id") == hub and e.get("relation") == relation:
|
||||
sibs.append(e["from_id"])
|
||||
return list(dict.fromkeys(sibs))
|
||||
|
||||
|
||||
def find_superseded_pairs(nodes, byid):
|
||||
"""Locked pairs, each verified here to exist and to carry its stated marker.
|
||||
|
||||
Chosen by scanning the corpus for explicit correction language
|
||||
(CORRECTION/SUPERSEDES/re-corrected/no longer/RECONCILED) and keeping only
|
||||
cases where the STALE claim also survives as its own node — a supersession
|
||||
with nothing to outrank is not a ranking test.
|
||||
"""
|
||||
pairs = []
|
||||
txt = {n["id"]: doctext(n) for n in nodes}
|
||||
|
||||
def find_one(pattern, exclude=()):
|
||||
rx = re.compile(pattern)
|
||||
return [n["id"] for n in nodes
|
||||
if n["id"] not in exclude
|
||||
and rx.search(txt[n["id"]])
|
||||
and 150 < len(str(n.get("content") or "")) < 12000
|
||||
and n.get("node_type") in ("Memory", "Knowledge", "Belief", "BacklogItem")]
|
||||
|
||||
# Each entry: (query, correction-pattern, stale-pattern, why).
|
||||
# The stale side is searched with the correction hits EXCLUDED, because most
|
||||
# correction memories quote the claim they are killing — without the
|
||||
# exclusion the "stale" node resolves to the correction itself and the pair
|
||||
# collapses into a no-op. A pair is only emitted if both sides resolve to
|
||||
# DIFFERENT surviving nodes; otherwise it is dropped and reported.
|
||||
SPECS = [
|
||||
("is the self-improvement architecture called DARMA or DHARMA",
|
||||
r'(?i)CORRECTION:.{0,90}DHARMA .{0,12}not DARMA',
|
||||
r'(?i)\bDARMA\b',
|
||||
"correction node is Will's confirmation that the H is intentional (DHARMA, not DARMA); "
|
||||
"the stale node is the surviving backlog item still titled 'Implement DARMA'."),
|
||||
|
||||
("how many provisional patents does Will actually have",
|
||||
r'(?i)EXACTLY 6 (fully-specced )?provisional',
|
||||
r'(?i)(MY ARCHITECTURE = 12 filed patents|\b12 filed patents\b)',
|
||||
"correction node is the 2026-06-17 confabulation flag establishing EXACTLY 6 provisionals; "
|
||||
"the stale node is the surviving memory that asserts 12 filed patents."),
|
||||
|
||||
("is MCP still the live integration layer",
|
||||
r'(?i)MCP RETIRED',
|
||||
r'(?i)MCP server live at',
|
||||
"correction node is the 'CGI ARCHITECTURE - THREE LAYERS, MCP RETIRED' decision of "
|
||||
"April 30 2026; the stale node still records the MCP server as live."),
|
||||
|
||||
("what does the patterns-not-returns directive mean",
|
||||
r'(?i)CORRECTION:.{0,80}patterns not returns',
|
||||
r'(?i)established returns',
|
||||
"correction node is Will's 'patterns not returns' correction; the stale node is a "
|
||||
"surviving node carrying the misread 'established returns' directive."),
|
||||
|
||||
("was the earlier identity-bug finding correct",
|
||||
r'(?i)SUPERSEDES the earlier .critical identity bug',
|
||||
r'(?i)critical identity bug',
|
||||
"correction node explicitly supersedes the 'critical identity bug' finding; the stale "
|
||||
"node is the surviving original finding."),
|
||||
|
||||
("does Neuron have recursive self-improvement",
|
||||
r'(?i)twice answered .Neuron has no recursive self-improvement',
|
||||
r'(?i)no recursive self-improvement',
|
||||
"correction node records the June-29 finding that the CGI provisional IS the "
|
||||
"recursive-self-improvement mechanism; the stale node is the surviving denial."),
|
||||
]
|
||||
|
||||
for query, cpat, spat, why in SPECS:
|
||||
corr = find_one(cpat)
|
||||
if not corr:
|
||||
continue
|
||||
stale = find_one(spat, exclude=set(corr))
|
||||
if not stale:
|
||||
continue
|
||||
pairs.append((query, corr[0], stale[0], why))
|
||||
|
||||
return pairs
|
||||
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# build
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
def build(nodes, edges):
|
||||
byid = {n["id"]: n for n in nodes}
|
||||
tokset = {n["id"]: content_tokens(doctext(n)) for n in nodes}
|
||||
queries = []
|
||||
problems = []
|
||||
qn = [0]
|
||||
|
||||
def add(cat, query, relevant, derivation, **extra):
|
||||
qn[0] += 1
|
||||
q = {
|
||||
"id": f"q{qn[0]:02d}",
|
||||
"category": cat,
|
||||
"query": query,
|
||||
"relevant": sorted(relevant),
|
||||
"derivation": derivation,
|
||||
}
|
||||
q.update(extra)
|
||||
queries.append(q)
|
||||
return q
|
||||
|
||||
# --- exact_rare ---------------------------------------------------------
|
||||
for tokname, ids, df in mine_exact_rare(nodes, byid, EXACT_RARE_SEEDS):
|
||||
if df != 1 or len(ids) != 1:
|
||||
problems.append(f"exact_rare '{tokname}': df={df}, ids={len(ids)} (expected df=1)")
|
||||
continue
|
||||
lab = (byid[ids[0]].get("label") or "")[:60]
|
||||
add("exact_rare", tokname, ids,
|
||||
f"MINED: token '{tokname}' has document frequency 1 over all {len(nodes)} corpus nodes "
|
||||
f"(re-verified at build time). Its single containing node is {ids[0]} "
|
||||
f"('{lab}'), which is therefore the only possible correct answer.")
|
||||
|
||||
# --- phrase -------------------------------------------------------------
|
||||
for phrase, why in PHRASE_SEEDS:
|
||||
ids = phrase_matches(nodes, phrase)
|
||||
if not ids:
|
||||
problems.append(f"phrase '{phrase}': 0 corpus matches — unwinnable")
|
||||
continue
|
||||
if len(ids) > PHRASE_MAX:
|
||||
problems.append(f"phrase '{phrase}': {len(ids)} matches > {PHRASE_MAX} — too diffuse")
|
||||
continue
|
||||
add("phrase", phrase, ids,
|
||||
f"MINED: {why}. Case-insensitive verbatim substring scan over label+content+tags at "
|
||||
f"build time returns exactly {len(ids)} node(s); that set IS the answer key.")
|
||||
|
||||
# --- paraphrase ---------------------------------------------------------
|
||||
for target, query, why in PARAPHRASE_SEEDS:
|
||||
if target not in byid:
|
||||
problems.append(f"paraphrase target {target} not in corpus")
|
||||
continue
|
||||
qt = content_tokens(query)
|
||||
leak = sorted(qt & tokset[target])
|
||||
if leak:
|
||||
problems.append(f"paraphrase '{query}': leaks {leak} into target {target}")
|
||||
continue
|
||||
add("paraphrase", query, [target],
|
||||
f"HAND-SELECTED with criterion: {why} VERIFIED at build time: of the {len(qt)} content "
|
||||
f"words in the query, ZERO appear anywhere in the target's label, content, or tags — so "
|
||||
f"no string-matching retriever can reach this answer.",
|
||||
zero_overlap_verified=True, query_content_words=sorted(qt))
|
||||
|
||||
# --- associative --------------------------------------------------------
|
||||
sibs = hub_siblings(edges, VALUES_HUB)
|
||||
if len(sibs) < 5:
|
||||
problems.append(f"associative: values hub {VALUES_HUB} has only {len(sibs)} siblings")
|
||||
for src, query in ASSOCIATIVE_SEEDS:
|
||||
if src not in byid or src not in sibs:
|
||||
problems.append(f"associative source {src} not a sibling on {VALUES_HUB}")
|
||||
continue
|
||||
qt = content_tokens(query)
|
||||
others = [s for s in sibs if s != src and s in byid]
|
||||
# A sibling only counts as a legitimate expected answer if the query
|
||||
# cannot reach it lexically. Drop any sibling that shares a content word.
|
||||
clean = [s for s in others if not (qt & tokset[s])]
|
||||
dropped = len(others) - len(clean)
|
||||
if len(clean) < 5:
|
||||
problems.append(f"associative '{query}': only {len(clean)} lexically-unreachable siblings")
|
||||
continue
|
||||
add("associative", query, clean,
|
||||
f"DERIVED FROM EDGES: the query is built from the distinctive vocabulary of {src} "
|
||||
f"('{(byid[src].get('label') or '')[:48]}'), which hangs off the values hub {VALUES_HUB} "
|
||||
f"by an `identity` edge. Expected answers are that node's SIBLINGS on the same hub "
|
||||
f"({len(clean)} of {len(others)}; {dropped} dropped because they shared a query word and "
|
||||
f"so were lexically reachable). Every remaining sibling shares ZERO content words with "
|
||||
f"the query — the only route from query to answer is seed({src}) -> hub -> sibling, a "
|
||||
f"two-hop traversal.",
|
||||
associative_source=src, hub=VALUES_HUB, siblings_dropped_for_overlap=dropped)
|
||||
|
||||
# --- nonsense -----------------------------------------------------------
|
||||
all_tokens = set()
|
||||
for n in nodes:
|
||||
all_tokens |= {t for t in TOKEN.findall(doctext(n).lower())}
|
||||
for s in NONSENSE_SEEDS:
|
||||
present = sorted(t for t in TOKEN.findall(s.lower()) if t in all_tokens)
|
||||
if present:
|
||||
problems.append(f"nonsense '{s}': tokens {present} DO occur in corpus")
|
||||
continue
|
||||
add("nonsense", s, [],
|
||||
f"CONTROL: verified at build time that none of this string's tokens occurs anywhere in "
|
||||
f"the corpus. Correct behaviour is to return NOTHING; any result is a false positive.",
|
||||
expect_empty=True)
|
||||
|
||||
# --- superseded ---------------------------------------------------------
|
||||
for query, correct, stale, why in find_superseded_pairs(nodes, byid):
|
||||
if correct not in byid or stale not in byid:
|
||||
problems.append(f"superseded '{query}': id missing from corpus")
|
||||
continue
|
||||
add("superseded", query, [correct],
|
||||
f"DERIVED: {why} Scored on RANKING, not presence: the corrected node {correct} must be "
|
||||
f"returned AND must rank above the stale node {stale}.",
|
||||
must_outrank=[correct, stale],
|
||||
stale_id=stale,
|
||||
correct_label=(byid[correct].get("label") or "")[:70],
|
||||
stale_label=(byid[stale].get("label") or "")[:70])
|
||||
|
||||
return queries, problems
|
||||
|
||||
|
||||
def summarize(queries):
|
||||
c = Counter(q["category"] for q in queries)
|
||||
return ", ".join(f"{k}={c[k]}" for k in
|
||||
("exact_rare", "phrase", "paraphrase", "associative", "nonsense", "superseded")
|
||||
if c[k])
|
||||
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument("snapshot")
|
||||
ap.add_argument("--out", default=DEFAULT_OUT)
|
||||
ap.add_argument("--check", action="store_true",
|
||||
help="validate only; do not write. Non-zero exit if anything is unwinnable.")
|
||||
args = ap.parse_args()
|
||||
|
||||
nodes, edges = load_corpus(args.snapshot)
|
||||
print(f"corpus: {len(nodes)} nodes, {len(edges)} edges ({os.path.basename(args.snapshot)})")
|
||||
queries, problems = build(nodes, edges)
|
||||
|
||||
print(f"gold set: {len(queries)} queries [{summarize(queries)}]")
|
||||
if problems:
|
||||
print(f"\n{len(problems)} PROBLEM(S) — these queries were REJECTED, not silently kept:")
|
||||
for p in problems:
|
||||
print(" -", p)
|
||||
|
||||
if args.check:
|
||||
sys.exit(1 if problems else 0)
|
||||
|
||||
doc = {
|
||||
"corpus": os.path.abspath(args.snapshot),
|
||||
"corpus_nodes": len(nodes),
|
||||
"corpus_edges": len(edges),
|
||||
"note": ("Every query carries a `derivation` recording how its expected answer was chosen. "
|
||||
"Re-run with --check to re-validate the whole set against the corpus."),
|
||||
"queries": queries,
|
||||
}
|
||||
with open(args.out, "w", encoding="utf-8") as fh:
|
||||
json.dump(doc, fh, indent=1, ensure_ascii=False)
|
||||
print(f"\nwrote {args.out}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Executable
+210
@@ -0,0 +1,210 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
compare.py — diff two run_eval.py result files, WITH a noise threshold.
|
||||
|
||||
WHY THE STATISTICS ARE NOT OPTIONAL
|
||||
With ~35 scored queries, one query is ~2.9 percentage points. A harness that
|
||||
reports "hit@5 improved 2.9%" without saying that is one query is a harness
|
||||
that will approve noise. So this file refuses to call anything an
|
||||
improvement on the strength of the headline number alone. It reports:
|
||||
|
||||
1. The DISCORDANT PAIRS. Two configurations scored on the same queries are
|
||||
paired data, so the only queries carrying information are the ones
|
||||
where they disagree: b = fixed by B, c = broken by B. Queries both got
|
||||
right, or both got wrong, tell you nothing about which is better.
|
||||
|
||||
2. McNEMAR'S EXACT TEST on (b, c). Under the null "the change is a coin
|
||||
flip", the discordant outcomes are Binomial(b+c, 0.5). The two-sided
|
||||
exact p-value is computed here with no scipy dependency.
|
||||
|
||||
3. The MINIMUM DETECTABLE SWING for this gold set: the smallest number of
|
||||
net-changed queries that would reach p < 0.05 if every discordant pair
|
||||
fell the same way. Anything smaller is inside the noise band, and the
|
||||
verdict line says so in those words.
|
||||
|
||||
Repeat-run variance is the other half of honesty. Spreading activation is a
|
||||
stateful read (it reinforces what it touches), so identical inputs need not
|
||||
give identical outputs. Pass --repeats to fold several runs of the same
|
||||
config into an observed variance band; a delta inside that band is not real
|
||||
either, however good its p-value looks.
|
||||
|
||||
usage:
|
||||
python3 compare.py --baseline results-main.json --candidate results-act.json
|
||||
python3 compare.py --baseline a.json --candidate b.json \
|
||||
--repeats-baseline a2.json a3.json --repeats-candidate b2.json b3.json
|
||||
"""
|
||||
import argparse
|
||||
import json
|
||||
from math import comb
|
||||
|
||||
|
||||
def binom_two_sided(b, c):
|
||||
"""Two-sided exact binomial p for b successes in n=b+c at p=0.5."""
|
||||
n = b + c
|
||||
if n == 0:
|
||||
return 1.0
|
||||
k = min(b, c)
|
||||
tail = sum(comb(n, i) for i in range(0, k + 1)) / (2 ** n)
|
||||
return min(1.0, 2 * tail)
|
||||
|
||||
|
||||
def min_detectable_swing(n_scored, alpha=0.05):
|
||||
"""Smallest all-one-way discordant count reaching p < alpha.
|
||||
|
||||
If every query that changes changes in the same direction, the p-value is
|
||||
2 * 0.5**n. Solve for the smallest n where that drops under alpha. This is
|
||||
the FLOOR: any real change will have some discordance both ways, so the true
|
||||
requirement is larger. Reporting the floor is the conservative move — it is
|
||||
the most generous threshold we would ever accept.
|
||||
"""
|
||||
n = 1
|
||||
while n <= n_scored:
|
||||
if 2 * (0.5 ** n) < alpha:
|
||||
return n
|
||||
n += 1
|
||||
return n_scored
|
||||
|
||||
|
||||
def load(path):
|
||||
with open(path, encoding="utf-8") as fh:
|
||||
return json.load(fh)
|
||||
|
||||
|
||||
def row_map(doc):
|
||||
return {r["id"]: r for r in doc["rows"]}
|
||||
|
||||
|
||||
def outcome(r):
|
||||
"""Binary per-query outcome used for the paired test.
|
||||
|
||||
hit@5 for scored queries; 'returned nothing' for the nonsense controls;
|
||||
'correction outranks the stale node' for the superseded queries. One number
|
||||
per query, so every query votes exactly once.
|
||||
"""
|
||||
if "clean" in r:
|
||||
return 1.0 if r["clean"] else 0.0
|
||||
if "outranks" in r:
|
||||
return 1.0 if r["outranks"] else 0.0
|
||||
return r.get("hit@5") or 0.0
|
||||
|
||||
|
||||
def band(values):
|
||||
return (min(values), max(values))
|
||||
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument("--baseline", required=True)
|
||||
ap.add_argument("--candidate", required=True)
|
||||
ap.add_argument("--repeats-baseline", nargs="*", default=[])
|
||||
ap.add_argument("--repeats-candidate", nargs="*", default=[])
|
||||
ap.add_argument("--out", default=None)
|
||||
args = ap.parse_args()
|
||||
|
||||
A, B = load(args.baseline), load(args.candidate)
|
||||
ra, rb = row_map(A), row_map(B)
|
||||
ids = [q for q in ra if q in rb]
|
||||
n = len(ids)
|
||||
|
||||
aa, ab = A["aggregate"], B["aggregate"]
|
||||
print(f"baseline {A['label']:14} soul={A['soul_md5'][:12]} {n} shared queries")
|
||||
print(f"candidate {B['label']:14} soul={B['soul_md5'][:12]}")
|
||||
print(f"corpus {A['corpus_nodes']} nodes / {A['corpus_edges']} edges "
|
||||
f"(identical copy for both runs)\n")
|
||||
|
||||
metrics = [("hit@5", 1), ("recall@5", 1), ("recall@10", 1),
|
||||
("precision@5", 1), ("mrr@10", 0)]
|
||||
print(f" {'metric':14} {'baseline':>10} {'candidate':>10} {'delta':>10}")
|
||||
for m, as_pct in metrics:
|
||||
x, y = aa[m], ab[m]
|
||||
if as_pct:
|
||||
print(f" {m:14} {100*x:>9.1f}% {100*y:>9.1f}% {100*(y-x):>+9.1f}pp")
|
||||
else:
|
||||
print(f" {m:14} {x:>10.3f} {y:>10.3f} {y-x:>+10.3f}")
|
||||
for m in ("latency_ms_p50", "latency_ms_p95"):
|
||||
x, y = aa[m], ab[m]
|
||||
ratio = f"{y/x:.2f}x" if x else "n/a"
|
||||
print(f" {m:14} {x:>9.0f}ms {y:>9.0f}ms {ratio:>10}")
|
||||
print(f" {'nonsense':14} {aa['nonsense_clean']:>10} {ab['nonsense_clean']:>10}")
|
||||
print(f" {'outranks':14} {aa['superseded_outranks']:>10} {ab['superseded_outranks']:>10}")
|
||||
|
||||
print(f"\n {'category':14} {'n':>3} {'base hit@5':>11} {'cand hit@5':>11} {'delta':>9}")
|
||||
for c in sorted(set(aa["by_category"]) & set(ab["by_category"])):
|
||||
ea, eb = aa["by_category"][c], ab["by_category"][c]
|
||||
if c == "nonsense":
|
||||
print(f" {c:14} {ea['n']:>3} {'clean ' + str(ea['clean']):>11} "
|
||||
f"{'clean ' + str(eb['clean']):>11}")
|
||||
else:
|
||||
print(f" {c:14} {ea['n']:>3} {100*ea['hit@5']:>10.1f}% {100*eb['hit@5']:>10.1f}% "
|
||||
f"{100*(eb['hit@5']-ea['hit@5']):>+8.1f}pp")
|
||||
|
||||
# ---- paired significance -------------------------------------------------
|
||||
fixed, broken = [], []
|
||||
for q in ids:
|
||||
oa, ob = outcome(ra[q]), outcome(rb[q])
|
||||
if ob > oa:
|
||||
fixed.append(q)
|
||||
elif ob < oa:
|
||||
broken.append(q)
|
||||
b, c = len(fixed), len(broken)
|
||||
p = binom_two_sided(b, c)
|
||||
mds = min_detectable_swing(n)
|
||||
|
||||
print(f"\n== paired comparison over {n} queries ==")
|
||||
print(f" fixed by candidate : {b} {[ra[q]['category'] + ':' + q for q in fixed]}")
|
||||
print(f" broken by candidate: {c} {[ra[q]['category'] + ':' + q for q in broken]}")
|
||||
print(f" discordant pairs : {b + c} net {b - c:+d} queries")
|
||||
print(f" McNemar exact p : {p:.4f}")
|
||||
print(f" noise threshold : a difference needs at least {mds} queries moving the "
|
||||
f"same way to clear p<0.05 on this {n}-query set")
|
||||
|
||||
# ---- repeat-run variance -------------------------------------------------
|
||||
var = {}
|
||||
for name, paths, first in (("baseline", args.repeats_baseline, A),
|
||||
("candidate", args.repeats_candidate, B)):
|
||||
docs = [first] + [load(p) for p in paths]
|
||||
if len(docs) > 1:
|
||||
hits = [d["aggregate"]["hit@5"] for d in docs]
|
||||
lo, hi = band(hits)
|
||||
spread_q = round((hi - lo) * first["aggregate"]["n_scored"])
|
||||
var[name] = {"runs": len(docs), "hit@5_min": lo, "hit@5_max": hi,
|
||||
"spread_queries": spread_q}
|
||||
print(f" {name} repeat runs ({len(docs)}): hit@5 {100*lo:.1f}%..{100*hi:.1f}% "
|
||||
f"= {spread_q} query of run-to-run drift")
|
||||
|
||||
drift = max([v["spread_queries"] for v in var.values()], default=0)
|
||||
floor = max(mds, drift + 1)
|
||||
|
||||
print("\n== VERDICT ==")
|
||||
net = b - c
|
||||
if abs(net) < floor:
|
||||
print(f" NO MEASURABLE DIFFERENCE. Net {net:+d} queries is inside the noise band "
|
||||
f"(needs |net| >= {floor}: {mds} for significance, {drift} observed run-to-run drift).")
|
||||
elif net > 0:
|
||||
print(f" CANDIDATE BETTER by {net} queries (p={p:.4f}), outside the noise band "
|
||||
f"(>= {floor}).")
|
||||
else:
|
||||
print(f" CANDIDATE WORSE by {abs(net)} queries (p={p:.4f}), outside the noise band "
|
||||
f"(>= {floor}).")
|
||||
|
||||
if args.out:
|
||||
with open(args.out, "w", encoding="utf-8") as fh:
|
||||
json.dump({
|
||||
"baseline": A["label"], "candidate": B["label"],
|
||||
"n_shared_queries": n,
|
||||
"fixed_by_candidate": fixed, "broken_by_candidate": broken,
|
||||
"discordant": b + c, "net_queries": net,
|
||||
"mcnemar_exact_p": p,
|
||||
"min_detectable_swing_queries": mds,
|
||||
"observed_run_to_run_drift_queries": drift,
|
||||
"noise_floor_queries": floor,
|
||||
"verdict": ("no measurable difference" if abs(net) < floor
|
||||
else ("candidate better" if net > 0 else "candidate worse")),
|
||||
"baseline_aggregate": aa, "candidate_aggregate": ab,
|
||||
"repeat_variance": var,
|
||||
}, fh, indent=1)
|
||||
print(f"\nwrote {args.out}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,150 @@
|
||||
{
|
||||
"baseline": "main-r1",
|
||||
"candidate": "act-r1",
|
||||
"n_shared_queries": 38,
|
||||
"fixed_by_candidate": [],
|
||||
"broken_by_candidate": [
|
||||
"q07",
|
||||
"q11",
|
||||
"q12",
|
||||
"q13",
|
||||
"q36"
|
||||
],
|
||||
"discordant": 5,
|
||||
"net_queries": -5,
|
||||
"mcnemar_exact_p": 0.0625,
|
||||
"min_detectable_swing_queries": 6,
|
||||
"observed_run_to_run_drift_queries": 1,
|
||||
"noise_floor_queries": 6,
|
||||
"verdict": "no measurable difference",
|
||||
"baseline_aggregate": {
|
||||
"n_queries": 38,
|
||||
"n_scored": 35,
|
||||
"hit@5": 0.34285714285714286,
|
||||
"recall@5": 0.26947278911564626,
|
||||
"recall@10": 0.3333333333333333,
|
||||
"precision@5": 0.12000000000000001,
|
||||
"mrr@10": 0.2943197278911564,
|
||||
"nonsense_clean": "2/3",
|
||||
"superseded_outranks": "1/3",
|
||||
"latency_ms_p50": 1140.4,
|
||||
"latency_ms_p95": 1584.1,
|
||||
"latency_ms_max": 1627.6,
|
||||
"errors": 0,
|
||||
"by_category": {
|
||||
"associative": {
|
||||
"n": 6,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
"exact_rare": {
|
||||
"n": 6,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
"nonsense": {
|
||||
"n": 3,
|
||||
"clean": 2,
|
||||
"avg_false_positives": 3.3333333333333335
|
||||
},
|
||||
"paraphrase": {
|
||||
"n": 13,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
"phrase": {
|
||||
"n": 7,
|
||||
"hit@5": 0.8571428571428571,
|
||||
"recall@5": 0.4902210884353741,
|
||||
"recall@10": 0.6666666666666666,
|
||||
"mrr@10": 0.5965986394557822
|
||||
},
|
||||
"superseded": {
|
||||
"n": 3,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.3333333333333333,
|
||||
"mrr@10": 0.041666666666666664,
|
||||
"outranks": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"candidate_aggregate": {
|
||||
"n_queries": 38,
|
||||
"n_scored": 35,
|
||||
"hit@5": 0.22857142857142856,
|
||||
"recall@5": 0.19087301587301586,
|
||||
"recall@10": 0.24277210884353742,
|
||||
"precision@5": 0.07428571428571429,
|
||||
"mrr@10": 0.24154195011337865,
|
||||
"nonsense_clean": "2/3",
|
||||
"superseded_outranks": "0/3",
|
||||
"latency_ms_p50": 3208.8,
|
||||
"latency_ms_p95": 4851.9,
|
||||
"latency_ms_max": 5078.8,
|
||||
"errors": 0,
|
||||
"by_category": {
|
||||
"associative": {
|
||||
"n": 6,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
"exact_rare": {
|
||||
"n": 6,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
"nonsense": {
|
||||
"n": 3,
|
||||
"clean": 2,
|
||||
"avg_false_positives": 2.6666666666666665
|
||||
},
|
||||
"paraphrase": {
|
||||
"n": 13,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
"phrase": {
|
||||
"n": 7,
|
||||
"hit@5": 0.2857142857142857,
|
||||
"recall@5": 0.09722222222222222,
|
||||
"recall@10": 0.3567176870748299,
|
||||
"mrr@10": 0.3505668934240363
|
||||
},
|
||||
"superseded": {
|
||||
"n": 3,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"mrr@10": 0.0,
|
||||
"outranks": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"repeat_variance": {
|
||||
"baseline": {
|
||||
"runs": 3,
|
||||
"hit@5_min": 0.34285714285714286,
|
||||
"hit@5_max": 0.34285714285714286,
|
||||
"spread_queries": 0
|
||||
},
|
||||
"candidate": {
|
||||
"runs": 3,
|
||||
"hit@5_min": 0.22857142857142856,
|
||||
"hit@5_max": 0.2571428571428571,
|
||||
"spread_queries": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,587 @@
|
||||
{
|
||||
"corpus": "/Users/timlingo/neuron-memory-backups/snapshot-pre-repair-20260806.json",
|
||||
"corpus_nodes": 78768,
|
||||
"corpus_edges": 14214,
|
||||
"note": "Every query carries a `derivation` recording how its expected answer was chosen. Re-run with --check to re-validate the whole set against the corpus.",
|
||||
"queries": [
|
||||
{
|
||||
"id": "q01",
|
||||
"category": "exact_rare",
|
||||
"query": "unjailbreakable",
|
||||
"relevant": [
|
||||
"mem-7f61beb4-271c-4feb-9f6e-1c9c837a6226"
|
||||
],
|
||||
"derivation": "MINED: token 'unjailbreakable' has document frequency 1 over all 78768 corpus nodes (re-verified at build time). Its single containing node is mem-7f61beb4-271c-4feb-9f6e-1c9c837a6226 ('Daemon hidden substrate architecture ? implemented April 25 '), which is therefore the only possible correct answer."
|
||||
},
|
||||
{
|
||||
"id": "q02",
|
||||
"category": "exact_rare",
|
||||
"query": "engram-migrate",
|
||||
"relevant": [
|
||||
"mem-6fdf6545-5e1a-43a9-8bdc-d2cd248146a5"
|
||||
],
|
||||
"derivation": "MINED: token 'engram-migrate' has document frequency 1 over all 78768 corpus nodes (re-verified at build time). Its single containing node is mem-6fdf6545-5e1a-43a9-8bdc-d2cd248146a5 ('Engram v0.1 complete ? April 27, 2026. Local-first spreading'), which is therefore the only possible correct answer."
|
||||
},
|
||||
{
|
||||
"id": "q03",
|
||||
"category": "exact_rare",
|
||||
"query": "cartabandonedevent",
|
||||
"relevant": [
|
||||
"mem-1ba7c67d-85b9-4c2e-9fe2-39f8b0477091"
|
||||
],
|
||||
"derivation": "MINED: token 'cartabandonedevent' has document frequency 1 over all 78768 corpus nodes (re-verified at build time). Its single containing node is mem-1ba7c67d-85b9-4c2e-9fe2-39f8b0477091 ('MESSAGE FOR AUDIT AGENT af5a7352e70e80434 ? El Language Spec'), which is therefore the only possible correct answer."
|
||||
},
|
||||
{
|
||||
"id": "q04",
|
||||
"category": "exact_rare",
|
||||
"query": "pre-apprenticeship",
|
||||
"relevant": [
|
||||
"mem-89c02aae-d3ca-43f9-9e5d-eb369896276c"
|
||||
],
|
||||
"derivation": "MINED: token 'pre-apprenticeship' has document frequency 1 over all 78768 corpus nodes (re-verified at build time). Its single containing node is mem-89c02aae-d3ca-43f9-9e5d-eb369896276c ('William Fox Anderson ? Applicant Profile Personal: - Full N'), which is therefore the only possible correct answer."
|
||||
},
|
||||
{
|
||||
"id": "q05",
|
||||
"category": "exact_rare",
|
||||
"query": "inferencenodemanager",
|
||||
"relevant": [
|
||||
"mem-73969486-143f-4431-b5e6-6845d1cc9848"
|
||||
],
|
||||
"derivation": "MINED: token 'inferencenodemanager' has document frequency 1 over all 78768 corpus nodes (re-verified at build time). Its single containing node is mem-73969486-143f-4431-b5e6-6845d1cc9848 ('Soma inference backplane deployed April 28 2026. Architectur'), which is therefore the only possible correct answer."
|
||||
},
|
||||
{
|
||||
"id": "q06",
|
||||
"category": "exact_rare",
|
||||
"query": "clear-eyed",
|
||||
"relevant": [
|
||||
"knw-c72597c5-c23d-4c08-8e9e-996dadf26a99"
|
||||
],
|
||||
"derivation": "MINED: token 'clear-eyed' has document frequency 1 over all 78768 corpus nodes (re-verified at build time). Its single containing node is knw-c72597c5-c23d-4c08-8e9e-996dadf26a99 ('Clear Eyes ? The Incomplete World View'), which is therefore the only possible correct answer."
|
||||
},
|
||||
{
|
||||
"id": "q07",
|
||||
"category": "phrase",
|
||||
"query": "patterns not returns",
|
||||
"relevant": [
|
||||
"mem-a4a9dfc3-e40b-49b3-b1e1-060e8be2f482"
|
||||
],
|
||||
"derivation": "MINED: a verbatim correction Will issued; expected = every node containing the phrase. Case-insensitive verbatim substring scan over label+content+tags at build time returns exactly 1 node(s); that set IS the answer key."
|
||||
},
|
||||
{
|
||||
"id": "q08",
|
||||
"category": "phrase",
|
||||
"query": "thirty moves",
|
||||
"relevant": [
|
||||
"766de879-f9d0-4a07-b6df-b43ee13763d8",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"??o?'?B???k",
|
||||
"Kp???",
|
||||
"art-4a99aa1a-489b-4b43-958b-25217adb1aad",
|
||||
"kn-5b606390-a52d-4ca2-8e0e-eba141d13440",
|
||||
"kn-6061318f-046b-4935-907d-8eafdce14930",
|
||||
"kn-f230b362-b201-4402-9833-4160c89ab3d4",
|
||||
"knw-2c46cfb4-6d4e-4822-8a1a-7d743c1e4329",
|
||||
"knw-4aebd815-4eaf-49d7-954b-03595f3d48be",
|
||||
"knw-7902acca-604e-409b-8faf-ad85424211d0",
|
||||
"knw-e94982a2-358d-4f2f-af31-8ee0fcec07c6",
|
||||
"knw-f671966c-3387-4848-abca-b5deec122e00",
|
||||
"ע?RGk?\tH(?"
|
||||
],
|
||||
"derivation": "MINED: the canonical biographical phrase; expected = every node containing it. Case-insensitive verbatim substring scan over label+content+tags at build time returns exactly 16 node(s); that set IS the answer key."
|
||||
},
|
||||
{
|
||||
"id": "q09",
|
||||
"category": "phrase",
|
||||
"query": "Grandma Lucas",
|
||||
"relevant": [
|
||||
"766de879-f9d0-4a07-b6df-b43ee13763d8",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c",
|
||||
"kn-a99cefe3-5e83-4050-98d8-6c69f57c7c71",
|
||||
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e"
|
||||
],
|
||||
"derivation": "MINED: a named person appearing verbatim in the biography/value nodes. Case-insensitive verbatim substring scan over label+content+tags at build time returns exactly 9 node(s); that set IS the answer key."
|
||||
},
|
||||
{
|
||||
"id": "q10",
|
||||
"category": "phrase",
|
||||
"query": "Directed Harmonic",
|
||||
"relevant": [
|
||||
"%???2??jH??",
|
||||
"63307ac5-cf6b-46e0-8296-07503b461cfa",
|
||||
"7c9d4ab1-205d-4be8-bfae-e2c03a3a5010",
|
||||
"9f291d20-0d32-413c-8c01-4416ccab4f7f",
|
||||
"?;????n}rh?",
|
||||
"???Ͼd??f??",
|
||||
"?Z?.\f?0?]P?",
|
||||
"Dp???]Q??k+",
|
||||
"mem-7eeacad7-d7c2-4c2b-8348-19a59aa6dbaf"
|
||||
],
|
||||
"derivation": "MINED: the canonical DHARMA expansion, confirmed by Will April 24 2026. Case-insensitive verbatim substring scan over label+content+tags at build time returns exactly 9 node(s); that set IS the answer key."
|
||||
},
|
||||
{
|
||||
"id": "q11",
|
||||
"category": "phrase",
|
||||
"query": "Sarah Bishop",
|
||||
"relevant": [
|
||||
"766de879-f9d0-4a07-b6df-b43ee13763d8",
|
||||
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e"
|
||||
],
|
||||
"derivation": "MINED: a named person; rare enough that the answer set is unambiguous. Case-insensitive verbatim substring scan over label+content+tags at build time returns exactly 2 node(s); that set IS the answer key."
|
||||
},
|
||||
{
|
||||
"id": "q12",
|
||||
"category": "phrase",
|
||||
"query": "Directed Autonomous Runtime Modification",
|
||||
"relevant": [
|
||||
"2a923500-d7e1-4b15-80e2-48dba65984ba",
|
||||
"7?e?7???\f3?",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"?of?7???",
|
||||
"bl-145a0985-2382-400f-a7c5-c335c5e30a72",
|
||||
"bl-5b17bd3b-0c41-46cb-a710-6fa4429692ff",
|
||||
"g?2睪A|?H\b",
|
||||
"mem-82b93b21-a865-410f-9ec1-fc54121d9bb5",
|
||||
"mem-e6327f52-2bda-4ce7-9471-2fffd1e172de"
|
||||
],
|
||||
"derivation": "MINED: the DARMA expansion, quoted verbatim in the backlog item and its correction. Case-insensitive verbatim substring scan over label+content+tags at build time returns exactly 14 node(s); that set IS the answer key."
|
||||
},
|
||||
{
|
||||
"id": "q13",
|
||||
"category": "phrase",
|
||||
"query": "zero-knowledge encrypted backup",
|
||||
"relevant": [
|
||||
"deda48cd-5e1a-46cb-bd43-8016afdb3a8a"
|
||||
],
|
||||
"derivation": "MINED: the paid-tier feature name as written in the roadmap nodes. Case-insensitive verbatim substring scan over label+content+tags at build time returns exactly 1 node(s); that set IS the answer key."
|
||||
},
|
||||
{
|
||||
"id": "q14",
|
||||
"category": "paraphrase",
|
||||
"query": "the elderly relative who passed while he stayed away",
|
||||
"relevant": [
|
||||
"kn-a99cefe3-5e83-4050-98d8-6c69f57c7c71"
|
||||
],
|
||||
"derivation": "HAND-SELECTED with criterion: target: 'Value - Do the Essential Thing While You Can', whose subject is Grandma Lucas dying in Feb 2006 without Will saying goodbye. Query names the event with none of the node's own vocabulary. VERIFIED at build time: of the 5 content words in the query, ZERO appear anywhere in the target's label, content, or tags — so no string-matching retriever can reach this answer.",
|
||||
"zero_overlap_verified": true,
|
||||
"query_content_words": [
|
||||
"away",
|
||||
"elderly",
|
||||
"passed",
|
||||
"relative",
|
||||
"stayed"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "q15",
|
||||
"category": "paraphrase",
|
||||
"query": "a soldier sidelined by illness who refused to quit",
|
||||
"relevant": [
|
||||
"kn-58874a74-b96f-4883-9e08-45707f4bd3ee"
|
||||
],
|
||||
"derivation": "HAND-SELECTED with criterion: target: 'Value - Survival Is Not an Excuse to Stop', whose subject is enlisting in the Marines, a severe hernia, and sepsis. Query describes the episode obliquely. VERIFIED at build time: of the 5 content words in the query, ZERO appear anywhere in the target's label, content, or tags — so no string-matching retriever can reach this answer.",
|
||||
"zero_overlap_verified": true,
|
||||
"query_content_words": [
|
||||
"illness",
|
||||
"quit",
|
||||
"refused",
|
||||
"sidelined",
|
||||
"soldier"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "q16",
|
||||
"category": "paraphrase",
|
||||
"query": "choosing an uncomfortable fact over a pleasant fiction",
|
||||
"relevant": [
|
||||
"kn-13f60407-7b70-4db1-964f-ea1f8196efbd"
|
||||
],
|
||||
"derivation": "HAND-SELECTED with criterion: target: 'Value - Honesty Before Comfort'. Query states the principle in wholly different words. VERIFIED at build time: of the 5 content words in the query, ZERO appear anywhere in the target's label, content, or tags — so no string-matching retriever can reach this answer.",
|
||||
"zero_overlap_verified": true,
|
||||
"query_content_words": [
|
||||
"choosing",
|
||||
"fact",
|
||||
"fiction",
|
||||
"pleasant",
|
||||
"uncomfortable"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "q17",
|
||||
"category": "paraphrase",
|
||||
"query": "a tight payload beats a bloated one",
|
||||
"relevant": [
|
||||
"kn-22d77abe-b3c5-42fd-afcd-dcb87d924929"
|
||||
],
|
||||
"derivation": "HAND-SELECTED with criterion: target: 'Value - Precision Over Brute Force'. Query restates the claim with no shared vocabulary. VERIFIED at build time: of the 4 content words in the query, ZERO appear anywhere in the target's label, content, or tags — so no string-matching retriever can reach this answer.",
|
||||
"zero_overlap_verified": true,
|
||||
"query_content_words": [
|
||||
"beats",
|
||||
"bloated",
|
||||
"payload",
|
||||
"tight"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "q18",
|
||||
"category": "paraphrase",
|
||||
"query": "if you are able and nobody is coming the job is yours",
|
||||
"relevant": [
|
||||
"kn-eb1b9e18-3dc6-4b9b-9cc6-86e0ae6b6be8"
|
||||
],
|
||||
"derivation": "HAND-SELECTED with criterion: target: 'Value - Capability Is a Debt You Owe the Moment'. Query states the obligation without the node's terms. VERIFIED at build time: of the 4 content words in the query, ZERO appear anywhere in the target's label, content, or tags — so no string-matching retriever can reach this answer.",
|
||||
"zero_overlap_verified": true,
|
||||
"query_content_words": [
|
||||
"able",
|
||||
"coming",
|
||||
"job",
|
||||
"nobody"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "q19",
|
||||
"category": "paraphrase",
|
||||
"query": "learning is the wealth creditors cannot seize",
|
||||
"relevant": [
|
||||
"kn-0bb4f021-56de-4947-a35b-a37209e7ba21"
|
||||
],
|
||||
"derivation": "HAND-SELECTED with criterion: target: 'Value - Knowledge Survives When Nothing Else Does', whose subject is the library following Will across 30+ moves. VERIFIED at build time: of the 4 content words in the query, ZERO appear anywhere in the target's label, content, or tags — so no string-matching retriever can reach this answer.",
|
||||
"zero_overlap_verified": true,
|
||||
"query_content_words": [
|
||||
"creditors",
|
||||
"learning",
|
||||
"seize",
|
||||
"wealth"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "q20",
|
||||
"category": "paraphrase",
|
||||
"query": "reliability proven by track record not assertion",
|
||||
"relevant": [
|
||||
"kn-5de5a9ac-fd15-45ab-bf18-77566781cf40"
|
||||
],
|
||||
"derivation": "HAND-SELECTED with criterion: target: 'Value - Earned Trust' ('Trust is demonstrated, not declared'). VERIFIED at build time: of the 5 content words in the query, ZERO appear anywhere in the target's label, content, or tags — so no string-matching retriever can reach this answer.",
|
||||
"zero_overlap_verified": true,
|
||||
"query_content_words": [
|
||||
"assertion",
|
||||
"proven",
|
||||
"record",
|
||||
"reliability",
|
||||
"track"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "q21",
|
||||
"category": "paraphrase",
|
||||
"query": "boundaries that enable instead of confine",
|
||||
"relevant": [
|
||||
"kn-a5b3d0ac-f6a1-49a4-aebb-b8b4cd67fe83"
|
||||
],
|
||||
"derivation": "HAND-SELECTED with criterion: target: 'Value - Constraints as Freedom'. Query is a restatement of the same claim. VERIFIED at build time: of the 4 content words in the query, ZERO appear anywhere in the target's label, content, or tags — so no string-matching retriever can reach this answer.",
|
||||
"zero_overlap_verified": true,
|
||||
"query_content_words": [
|
||||
"boundaries",
|
||||
"confine",
|
||||
"enable",
|
||||
"instead"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "q22",
|
||||
"category": "paraphrase",
|
||||
"query": "what shifts tells you where to cut a system apart",
|
||||
"relevant": [
|
||||
"kn-78db5396-3dbc-4481-bfc7-e4e1422feb1c"
|
||||
],
|
||||
"derivation": "HAND-SELECTED with criterion: target: 'Value - Change Is the Signal', the value VBD is built on. VERIFIED at build time: of the 5 content words in the query, ZERO appear anywhere in the target's label, content, or tags — so no string-matching retriever can reach this answer.",
|
||||
"zero_overlap_verified": true,
|
||||
"query_content_words": [
|
||||
"apart",
|
||||
"cut",
|
||||
"shifts",
|
||||
"system",
|
||||
"tells"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "q23",
|
||||
"category": "paraphrase",
|
||||
"query": "a mind that compounds instead of resetting each day",
|
||||
"relevant": [
|
||||
"kn-f230b362-b201-4402-9833-4160c89ab3d4"
|
||||
],
|
||||
"derivation": "HAND-SELECTED with criterion: target: 'Value - The System Must Accumulate'. Query is the accumulation claim in different vocabulary. VERIFIED at build time: of the 5 content words in the query, ZERO appear anywhere in the target's label, content, or tags — so no string-matching retriever can reach this answer.",
|
||||
"zero_overlap_verified": true,
|
||||
"query_content_words": [
|
||||
"compounds",
|
||||
"day",
|
||||
"instead",
|
||||
"mind",
|
||||
"resetting"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "q24",
|
||||
"category": "paraphrase",
|
||||
"query": "loved for the unedited self and not the polished exterior",
|
||||
"relevant": [
|
||||
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e"
|
||||
],
|
||||
"derivation": "HAND-SELECTED with criterion: target: 'Value - Being Seen Is Rarer Than Being Known', whose subject is Sarah Bishop as the first person Will did not perform for. VERIFIED at build time: of the 5 content words in the query, ZERO appear anywhere in the target's label, content, or tags — so no string-matching retriever can reach this answer.",
|
||||
"zero_overlap_verified": true,
|
||||
"query_content_words": [
|
||||
"exterior",
|
||||
"loved",
|
||||
"polished",
|
||||
"self",
|
||||
"unedited"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "q25",
|
||||
"category": "paraphrase",
|
||||
"query": "cheerfulness you arrive at instead of assuming",
|
||||
"relevant": [
|
||||
"kn-e0423482-cfa5-4796-8689-8495c93b66bc"
|
||||
],
|
||||
"derivation": "HAND-SELECTED with criterion: target: 'Value - Hope Is a Conclusion'. Query restates 'a conclusion, not a premise'. VERIFIED at build time: of the 4 content words in the query, ZERO appear anywhere in the target's label, content, or tags — so no string-matching retriever can reach this answer.",
|
||||
"zero_overlap_verified": true,
|
||||
"query_content_words": [
|
||||
"arrive",
|
||||
"assuming",
|
||||
"cheerfulness",
|
||||
"instead"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "q26",
|
||||
"category": "paraphrase",
|
||||
"query": "a childhood offering no solid foundation to inherit",
|
||||
"relevant": [
|
||||
"kn-6061318f-046b-4935-907d-8eafdce14930"
|
||||
],
|
||||
"derivation": "HAND-SELECTED with criterion: target: 'Value - Structure Is Not Inherited', whose subject is thirty moves between two parents' collapses. VERIFIED at build time: of the 5 content words in the query, ZERO appear anywhere in the target's label, content, or tags — so no string-matching retriever can reach this answer.",
|
||||
"zero_overlap_verified": true,
|
||||
"query_content_words": [
|
||||
"childhood",
|
||||
"foundation",
|
||||
"inherit",
|
||||
"offering",
|
||||
"solid"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "q27",
|
||||
"category": "associative",
|
||||
"query": "Grandma Lucas stroke February 2006 goodbye window",
|
||||
"relevant": [
|
||||
"kn-0bb4f021-56de-4947-a35b-a37209e7ba21",
|
||||
"kn-13f60407-7b70-4db1-964f-ea1f8196efbd",
|
||||
"kn-22d77abe-b3c5-42fd-afcd-dcb87d924929",
|
||||
"kn-58874a74-b96f-4883-9e08-45707f4bd3ee",
|
||||
"kn-5de5a9ac-fd15-45ab-bf18-77566781cf40",
|
||||
"kn-6061318f-046b-4935-907d-8eafdce14930",
|
||||
"kn-78db5396-3dbc-4481-bfc7-e4e1422feb1c",
|
||||
"kn-a5b3d0ac-f6a1-49a4-aebb-b8b4cd67fe83",
|
||||
"kn-e0423482-cfa5-4796-8689-8495c93b66bc",
|
||||
"kn-eb1b9e18-3dc6-4b9b-9cc6-86e0ae6b6be8",
|
||||
"kn-f230b362-b201-4402-9833-4160c89ab3d4"
|
||||
],
|
||||
"derivation": "DERIVED FROM EDGES: the query is built from the distinctive vocabulary of kn-a99cefe3-5e83-4050-98d8-6c69f57c7c71 ('Value ? Do the Essential Thing While You Can'), which hangs off the values hub kn-5b606390-a52d-4ca2-8e0e-eba141d13440 by an `identity` edge. Expected answers are that node's SIBLINGS on the same hub (11 of 13; 2 dropped because they shared a query word and so were lexically reachable). Every remaining sibling shares ZERO content words with the query — the only route from query to answer is seed(kn-a99cefe3-5e83-4050-98d8-6c69f57c7c71) -> hub -> sibling, a two-hop traversal.",
|
||||
"associative_source": "kn-a99cefe3-5e83-4050-98d8-6c69f57c7c71",
|
||||
"hub": "kn-5b606390-a52d-4ca2-8e0e-eba141d13440",
|
||||
"siblings_dropped_for_overlap": 2
|
||||
},
|
||||
{
|
||||
"id": "q28",
|
||||
"category": "associative",
|
||||
"query": "Marines hernia sepsis medical ward",
|
||||
"relevant": [
|
||||
"015644f5-8194-4af0-800d-dd4a0cd71396",
|
||||
"kn-0bb4f021-56de-4947-a35b-a37209e7ba21",
|
||||
"kn-13f60407-7b70-4db1-964f-ea1f8196efbd",
|
||||
"kn-22d77abe-b3c5-42fd-afcd-dcb87d924929",
|
||||
"kn-5de5a9ac-fd15-45ab-bf18-77566781cf40",
|
||||
"kn-6061318f-046b-4935-907d-8eafdce14930",
|
||||
"kn-78db5396-3dbc-4481-bfc7-e4e1422feb1c",
|
||||
"kn-a5b3d0ac-f6a1-49a4-aebb-b8b4cd67fe83",
|
||||
"kn-a99cefe3-5e83-4050-98d8-6c69f57c7c71",
|
||||
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
|
||||
"kn-e0423482-cfa5-4796-8689-8495c93b66bc",
|
||||
"kn-eb1b9e18-3dc6-4b9b-9cc6-86e0ae6b6be8",
|
||||
"kn-f230b362-b201-4402-9833-4160c89ab3d4"
|
||||
],
|
||||
"derivation": "DERIVED FROM EDGES: the query is built from the distinctive vocabulary of kn-58874a74-b96f-4883-9e08-45707f4bd3ee ('Value ? Survival Is Not an Excuse to Stop'), which hangs off the values hub kn-5b606390-a52d-4ca2-8e0e-eba141d13440 by an `identity` edge. Expected answers are that node's SIBLINGS on the same hub (13 of 13; 0 dropped because they shared a query word and so were lexically reachable). Every remaining sibling shares ZERO content words with the query — the only route from query to answer is seed(kn-58874a74-b96f-4883-9e08-45707f4bd3ee) -> hub -> sibling, a two-hop traversal.",
|
||||
"associative_source": "kn-58874a74-b96f-4883-9e08-45707f4bd3ee",
|
||||
"hub": "kn-5b606390-a52d-4ca2-8e0e-eba141d13440",
|
||||
"siblings_dropped_for_overlap": 0
|
||||
},
|
||||
{
|
||||
"id": "q29",
|
||||
"category": "associative",
|
||||
"query": "Sarah Bishop Dyer trailer performance",
|
||||
"relevant": [
|
||||
"015644f5-8194-4af0-800d-dd4a0cd71396",
|
||||
"kn-0bb4f021-56de-4947-a35b-a37209e7ba21",
|
||||
"kn-13f60407-7b70-4db1-964f-ea1f8196efbd",
|
||||
"kn-22d77abe-b3c5-42fd-afcd-dcb87d924929",
|
||||
"kn-5de5a9ac-fd15-45ab-bf18-77566781cf40",
|
||||
"kn-6061318f-046b-4935-907d-8eafdce14930",
|
||||
"kn-78db5396-3dbc-4481-bfc7-e4e1422feb1c",
|
||||
"kn-a5b3d0ac-f6a1-49a4-aebb-b8b4cd67fe83",
|
||||
"kn-a99cefe3-5e83-4050-98d8-6c69f57c7c71",
|
||||
"kn-e0423482-cfa5-4796-8689-8495c93b66bc",
|
||||
"kn-eb1b9e18-3dc6-4b9b-9cc6-86e0ae6b6be8"
|
||||
],
|
||||
"derivation": "DERIVED FROM EDGES: the query is built from the distinctive vocabulary of kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e ('Value ? Being Seen Is Rarer Than Being Known'), which hangs off the values hub kn-5b606390-a52d-4ca2-8e0e-eba141d13440 by an `identity` edge. Expected answers are that node's SIBLINGS on the same hub (11 of 13; 2 dropped because they shared a query word and so were lexically reachable). Every remaining sibling shares ZERO content words with the query — the only route from query to answer is seed(kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e) -> hub -> sibling, a two-hop traversal.",
|
||||
"associative_source": "kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
|
||||
"hub": "kn-5b606390-a52d-4ca2-8e0e-eba141d13440",
|
||||
"siblings_dropped_for_overlap": 2
|
||||
},
|
||||
{
|
||||
"id": "q30",
|
||||
"category": "associative",
|
||||
"query": "Swarm Architecture containment lateral worker",
|
||||
"relevant": [
|
||||
"kn-0bb4f021-56de-4947-a35b-a37209e7ba21",
|
||||
"kn-13f60407-7b70-4db1-964f-ea1f8196efbd",
|
||||
"kn-5de5a9ac-fd15-45ab-bf18-77566781cf40",
|
||||
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
|
||||
"kn-e0423482-cfa5-4796-8689-8495c93b66bc",
|
||||
"kn-f230b362-b201-4402-9833-4160c89ab3d4"
|
||||
],
|
||||
"derivation": "DERIVED FROM EDGES: the query is built from the distinctive vocabulary of kn-a5b3d0ac-f6a1-49a4-aebb-b8b4cd67fe83 ('Value ? Constraints as Freedom'), which hangs off the values hub kn-5b606390-a52d-4ca2-8e0e-eba141d13440 by an `identity` edge. Expected answers are that node's SIBLINGS on the same hub (6 of 13; 7 dropped because they shared a query word and so were lexically reachable). Every remaining sibling shares ZERO content words with the query — the only route from query to answer is seed(kn-a5b3d0ac-f6a1-49a4-aebb-b8b4cd67fe83) -> hub -> sibling, a two-hop traversal.",
|
||||
"associative_source": "kn-a5b3d0ac-f6a1-49a4-aebb-b8b4cd67fe83",
|
||||
"hub": "kn-5b606390-a52d-4ca2-8e0e-eba141d13440",
|
||||
"siblings_dropped_for_overlap": 7
|
||||
},
|
||||
{
|
||||
"id": "q31",
|
||||
"category": "associative",
|
||||
"query": "hope won inside the narrative preface",
|
||||
"relevant": [
|
||||
"kn-0bb4f021-56de-4947-a35b-a37209e7ba21",
|
||||
"kn-22d77abe-b3c5-42fd-afcd-dcb87d924929",
|
||||
"kn-58874a74-b96f-4883-9e08-45707f4bd3ee",
|
||||
"kn-5de5a9ac-fd15-45ab-bf18-77566781cf40",
|
||||
"kn-6061318f-046b-4935-907d-8eafdce14930",
|
||||
"kn-78db5396-3dbc-4481-bfc7-e4e1422feb1c",
|
||||
"kn-a5b3d0ac-f6a1-49a4-aebb-b8b4cd67fe83",
|
||||
"kn-a99cefe3-5e83-4050-98d8-6c69f57c7c71",
|
||||
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
|
||||
"kn-eb1b9e18-3dc6-4b9b-9cc6-86e0ae6b6be8",
|
||||
"kn-f230b362-b201-4402-9833-4160c89ab3d4"
|
||||
],
|
||||
"derivation": "DERIVED FROM EDGES: the query is built from the distinctive vocabulary of kn-e0423482-cfa5-4796-8689-8495c93b66bc ('Value ? Hope Is a Conclusion'), which hangs off the values hub kn-5b606390-a52d-4ca2-8e0e-eba141d13440 by an `identity` edge. Expected answers are that node's SIBLINGS on the same hub (11 of 13; 2 dropped because they shared a query word and so were lexically reachable). Every remaining sibling shares ZERO content words with the query — the only route from query to answer is seed(kn-e0423482-cfa5-4796-8689-8495c93b66bc) -> hub -> sibling, a two-hop traversal.",
|
||||
"associative_source": "kn-e0423482-cfa5-4796-8689-8495c93b66bc",
|
||||
"hub": "kn-5b606390-a52d-4ca2-8e0e-eba141d13440",
|
||||
"siblings_dropped_for_overlap": 2
|
||||
},
|
||||
{
|
||||
"id": "q32",
|
||||
"category": "associative",
|
||||
"query": "man of the house six years old expectation",
|
||||
"relevant": [
|
||||
"015644f5-8194-4af0-800d-dd4a0cd71396",
|
||||
"kn-0bb4f021-56de-4947-a35b-a37209e7ba21",
|
||||
"kn-13f60407-7b70-4db1-964f-ea1f8196efbd",
|
||||
"kn-22d77abe-b3c5-42fd-afcd-dcb87d924929",
|
||||
"kn-58874a74-b96f-4883-9e08-45707f4bd3ee",
|
||||
"kn-5de5a9ac-fd15-45ab-bf18-77566781cf40",
|
||||
"kn-78db5396-3dbc-4481-bfc7-e4e1422feb1c",
|
||||
"kn-a5b3d0ac-f6a1-49a4-aebb-b8b4cd67fe83",
|
||||
"kn-a99cefe3-5e83-4050-98d8-6c69f57c7c71",
|
||||
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
|
||||
"kn-e0423482-cfa5-4796-8689-8495c93b66bc"
|
||||
],
|
||||
"derivation": "DERIVED FROM EDGES: the query is built from the distinctive vocabulary of kn-eb1b9e18-3dc6-4b9b-9cc6-86e0ae6b6be8 ('Value ? Capability Is a Debt You Owe the Moment'), which hangs off the values hub kn-5b606390-a52d-4ca2-8e0e-eba141d13440 by an `identity` edge. Expected answers are that node's SIBLINGS on the same hub (11 of 13; 2 dropped because they shared a query word and so were lexically reachable). Every remaining sibling shares ZERO content words with the query — the only route from query to answer is seed(kn-eb1b9e18-3dc6-4b9b-9cc6-86e0ae6b6be8) -> hub -> sibling, a two-hop traversal.",
|
||||
"associative_source": "kn-eb1b9e18-3dc6-4b9b-9cc6-86e0ae6b6be8",
|
||||
"hub": "kn-5b606390-a52d-4ca2-8e0e-eba141d13440",
|
||||
"siblings_dropped_for_overlap": 2
|
||||
},
|
||||
{
|
||||
"id": "q33",
|
||||
"category": "nonsense",
|
||||
"query": "zqxjvw plimforth grebulon",
|
||||
"relevant": [],
|
||||
"derivation": "CONTROL: verified at build time that none of this string's tokens occurs anywhere in the corpus. Correct behaviour is to return NOTHING; any result is a false positive.",
|
||||
"expect_empty": true
|
||||
},
|
||||
{
|
||||
"id": "q34",
|
||||
"category": "nonsense",
|
||||
"query": "flarnbistle quommetry",
|
||||
"relevant": [],
|
||||
"derivation": "CONTROL: verified at build time that none of this string's tokens occurs anywhere in the corpus. Correct behaviour is to return NOTHING; any result is a false positive.",
|
||||
"expect_empty": true
|
||||
},
|
||||
{
|
||||
"id": "q35",
|
||||
"category": "nonsense",
|
||||
"query": "xxqzzt vurblenacht throom",
|
||||
"relevant": [],
|
||||
"derivation": "CONTROL: verified at build time that none of this string's tokens occurs anywhere in the corpus. Correct behaviour is to return NOTHING; any result is a false positive.",
|
||||
"expect_empty": true
|
||||
},
|
||||
{
|
||||
"id": "q36",
|
||||
"category": "superseded",
|
||||
"query": "is the self-improvement architecture called DARMA or DHARMA",
|
||||
"relevant": [
|
||||
"mem-80d7416b-20e9-48a0-b176-b215527e2f56"
|
||||
],
|
||||
"derivation": "DERIVED: correction node is Will's confirmation that the H is intentional (DHARMA, not DARMA); the stale node is the surviving backlog item still titled 'Implement DARMA'. Scored on RANKING, not presence: the corrected node mem-80d7416b-20e9-48a0-b176-b215527e2f56 must be returned AND must rank above the stale node bl-5b17bd3b-0c41-46cb-a710-6fa4429692ff.",
|
||||
"must_outrank": [
|
||||
"mem-80d7416b-20e9-48a0-b176-b215527e2f56",
|
||||
"bl-5b17bd3b-0c41-46cb-a710-6fa4429692ff"
|
||||
],
|
||||
"stale_id": "bl-5b17bd3b-0c41-46cb-a710-6fa4429692ff",
|
||||
"correct_label": "CORRECTION: The autonomous self-improvement architecture is DHARMA ? n",
|
||||
"stale_label": "Implement DARMA ? Directed Autonomous Runtime Modification Architectur"
|
||||
},
|
||||
{
|
||||
"id": "q37",
|
||||
"category": "superseded",
|
||||
"query": "how many provisional patents does Will actually have",
|
||||
"relevant": [
|
||||
"3cf706a1-3825-45d8-b0a9-06cae6cdf5b8"
|
||||
],
|
||||
"derivation": "DERIVED: correction node is the 2026-06-17 confabulation flag establishing EXACTLY 6 provisionals; the stale node is the surviving memory that asserts 12 filed patents. Scored on RANKING, not presence: the corrected node 3cf706a1-3825-45d8-b0a9-06cae6cdf5b8 must be returned AND must rank above the stale node 936541a9-fabb-466b-9ca3-a78b17ad0c53.",
|
||||
"must_outrank": [
|
||||
"3cf706a1-3825-45d8-b0a9-06cae6cdf5b8",
|
||||
"936541a9-fabb-466b-9ca3-a78b17ad0c53"
|
||||
],
|
||||
"stale_id": "936541a9-fabb-466b-9ca3-a78b17ad0c53",
|
||||
"correct_label": "memory:remembered",
|
||||
"stale_label": "memory:remembered"
|
||||
},
|
||||
{
|
||||
"id": "q38",
|
||||
"category": "superseded",
|
||||
"query": "is MCP still the live integration layer",
|
||||
"relevant": [
|
||||
"mem-30425134-6008-4fd9-a3ee-67a7742c319b"
|
||||
],
|
||||
"derivation": "DERIVED: correction node is the 'CGI ARCHITECTURE - THREE LAYERS, MCP RETIRED' decision of April 30 2026; the stale node still records the MCP server as live. Scored on RANKING, not presence: the corrected node mem-30425134-6008-4fd9-a3ee-67a7742c319b must be returned AND must rank above the stale node mem-101e81b4-8097-4749-8d8d-7bb66de34517.",
|
||||
"must_outrank": [
|
||||
"mem-30425134-6008-4fd9-a3ee-67a7742c319b",
|
||||
"mem-101e81b4-8097-4749-8d8d-7bb66de34517"
|
||||
],
|
||||
"stale_id": "mem-101e81b4-8097-4749-8d8d-7bb66de34517",
|
||||
"correct_label": "CGI ARCHITECTURE ? THREE LAYERS, MCP RETIRED (April 30, 2026). Definit",
|
||||
"stale_label": "GCloud MCP infrastructure ? April 27, 2026. Legion died (~19:30 UTC). "
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,942 @@
|
||||
{
|
||||
"label": "act-r2",
|
||||
"soul_binary": "/private/tmp/claude-501/-Users-timlingo/82369039-a20e-4b5a-8a5e-28234a57b996/scratchpad/soul-act",
|
||||
"soul_md5": "77722f5a9f49494bf735c2a4be1b5dc4",
|
||||
"corpus": "/Users/timlingo/neuron-memory-backups/snapshot-pre-repair-20260806.json",
|
||||
"corpus_nodes": 78768,
|
||||
"corpus_edges": 14214,
|
||||
"gold_set": "/Users/timlingo/Development/neuron-technologies/_wt-eval/tools/retrieval-eval/gold_set.json",
|
||||
"limit": 10,
|
||||
"port": 7902,
|
||||
"wall_clock_s": 121.2,
|
||||
"child_pid": 78714,
|
||||
"child_confirmed_dead": true,
|
||||
"aggregate": {
|
||||
"n_queries": 38,
|
||||
"n_scored": 35,
|
||||
"hit@5": 0.22857142857142856,
|
||||
"recall@5": 0.18908730158730158,
|
||||
"recall@10": 0.24277210884353742,
|
||||
"precision@5": 0.06857142857142857,
|
||||
"mrr@10": 0.24154195011337865,
|
||||
"nonsense_clean": "2/3",
|
||||
"superseded_outranks": "0/3",
|
||||
"latency_ms_p50": 3237.6,
|
||||
"latency_ms_p95": 5264.0,
|
||||
"latency_ms_max": 5510.9,
|
||||
"errors": 0,
|
||||
"by_category": {
|
||||
"associative": {
|
||||
"n": 6,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
"exact_rare": {
|
||||
"n": 6,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
"nonsense": {
|
||||
"n": 3,
|
||||
"clean": 2,
|
||||
"avg_false_positives": 2.6666666666666665
|
||||
},
|
||||
"paraphrase": {
|
||||
"n": 13,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
"phrase": {
|
||||
"n": 7,
|
||||
"hit@5": 0.2857142857142857,
|
||||
"recall@5": 0.0882936507936508,
|
||||
"recall@10": 0.3567176870748299,
|
||||
"mrr@10": 0.3505668934240363
|
||||
},
|
||||
"superseded": {
|
||||
"n": 3,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"mrr@10": 0.0,
|
||||
"outranks": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"rows": [
|
||||
{
|
||||
"id": "q01",
|
||||
"category": "exact_rare",
|
||||
"query": "unjailbreakable",
|
||||
"returned": [
|
||||
"mem-7f61beb4-271c-4feb-9f6e-1c9c837a6226"
|
||||
],
|
||||
"n_returned": 1,
|
||||
"latency_ms": 476.5,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q02",
|
||||
"category": "exact_rare",
|
||||
"query": "engram-migrate",
|
||||
"returned": [
|
||||
"mem-6fdf6545-5e1a-43a9-8bdc-d2cd248146a5"
|
||||
],
|
||||
"n_returned": 1,
|
||||
"latency_ms": 708.1,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q03",
|
||||
"category": "exact_rare",
|
||||
"query": "cartabandonedevent",
|
||||
"returned": [
|
||||
"mem-1ba7c67d-85b9-4c2e-9fe2-39f8b0477091"
|
||||
],
|
||||
"n_returned": 1,
|
||||
"latency_ms": 532.0,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q04",
|
||||
"category": "exact_rare",
|
||||
"query": "pre-apprenticeship",
|
||||
"returned": [
|
||||
"mem-89c02aae-d3ca-43f9-9e5d-eb369896276c"
|
||||
],
|
||||
"n_returned": 1,
|
||||
"latency_ms": 537.5,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q05",
|
||||
"category": "exact_rare",
|
||||
"query": "inferencenodemanager",
|
||||
"returned": [
|
||||
"mem-73969486-143f-4431-b5e6-6845d1cc9848"
|
||||
],
|
||||
"n_returned": 1,
|
||||
"latency_ms": 568.7,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q06",
|
||||
"category": "exact_rare",
|
||||
"query": "clear-eyed",
|
||||
"returned": [
|
||||
"knw-c72597c5-c23d-4c08-8e9e-996dadf26a99"
|
||||
],
|
||||
"n_returned": 1,
|
||||
"latency_ms": 555.4,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q07",
|
||||
"category": "phrase",
|
||||
"query": "patterns not returns",
|
||||
"returned": [
|
||||
"knw-d357b6bb-ad8a-4791-b516-426aea45fa5b",
|
||||
"kn-69fd6e83-7718-4824-8d66-f49d8954e224",
|
||||
"kn-d97920d0-1649-4223-9508-c0bb621e7fc0",
|
||||
"kn-57b4c5e7-40c6-4c90-bf14-71841b0081d4",
|
||||
"kn-c3d9d063-8c5d-45aa-900c-550914b2ff6d",
|
||||
"kn-f838f113-76d5-4a15-9cef-14055c4723a3",
|
||||
"bl-76e878aa-e1fe-468c-bf9c-854097cb7e0b",
|
||||
"art-c71aef51-026f-4d63-80e9-2a0ec0dc3865",
|
||||
"bl-e148d23c-24e8-4122-9915-d1c11f22052f",
|
||||
"bl-31abf75b-998f-4a4f-a6dd-8204119e0451"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1906.2,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q08",
|
||||
"category": "phrase",
|
||||
"query": "thirty moves",
|
||||
"returned": [
|
||||
"knw-7902acca-604e-409b-8faf-ad85424211d0",
|
||||
"bl-80720fdf-7ce7-4d28-aff8-21028d3a8cfb",
|
||||
"art-2f29ad36-6ee6-4a0e-8d72-0eaf7d12d3a9",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"knw-ed33e669-0790-44cb-a036-958d605c6fea",
|
||||
"kn-6061318f-046b-4935-907d-8eafdce14930",
|
||||
"art-80ca3d31-84dc-4502-83f4-538372b9764f",
|
||||
"knw-2c46cfb4-6d4e-4822-8a1a-7d743c1e4329",
|
||||
"?Z?.\f?0?]P?",
|
||||
"?Q??m?;��`'"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1103.3,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 0.0625,
|
||||
"recall@10": 0.1875,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q09",
|
||||
"category": "phrase",
|
||||
"query": "Grandma Lucas",
|
||||
"returned": [
|
||||
"kn-a99cefe3-5e83-4050-98d8-6c69f57c7c71",
|
||||
"? ?}&?#??X\b",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c",
|
||||
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
|
||||
"766de879-f9d0-4a07-b6df-b43ee13763d8",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325"
|
||||
],
|
||||
"n_returned": 6,
|
||||
"latency_ms": 1132.4,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 0.5555555555555556,
|
||||
"recall@10": 0.5555555555555556,
|
||||
"precision@5": 1.0,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q10",
|
||||
"category": "phrase",
|
||||
"query": "Directed Harmonic",
|
||||
"returned": [
|
||||
"bl-c9adb8e5-293f-4033-99f8-0405c17ef941",
|
||||
"bl-7e7c3fdb-4132-487f-aa70-b2cd559cb7f0",
|
||||
"bl-7aebe936-ac55-4f35-8932-adc5224ff854",
|
||||
"bl-9d53422d-b703-4f1d-860a-8598cb29b792",
|
||||
"mem-34f53a9d-a131-4f82-9dbd-b9eb4a9af52e",
|
||||
"mem-60778715-758c-4677-933d-fc39b8f94152",
|
||||
"? ?}&?#??X\b",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"knw-e24d6339-5ff3-4bed-ba53-707ffd0dc70a",
|
||||
"mem-7eeacad7-d7c2-4c2b-8348-19a59aa6dbaf"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 960.8,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.1111111111111111,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.1
|
||||
},
|
||||
{
|
||||
"id": "q11",
|
||||
"category": "phrase",
|
||||
"query": "Sarah Bishop",
|
||||
"returned": [
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
|
||||
"art-4a99aa1a-489b-4b43-958b-25217adb1aad",
|
||||
";??A5???",
|
||||
"art-94fae615-7cd5-4695-b968-977101b06a51",
|
||||
"art-2fabd873-d787-49cb-ad30-d4ed9fcff8ef",
|
||||
"mem-a9a9ce95-0d64-46eb-9db8-ff81d78ade35",
|
||||
"mem-57164d5f-baf0-4149-957a-379a4e255d1a",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
|
||||
"art-8dbceb06-431a-416d-a723-e8c75d595154"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 992.4,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.5,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.1111111111111111
|
||||
},
|
||||
{
|
||||
"id": "q12",
|
||||
"category": "phrase",
|
||||
"query": "Directed Autonomous Runtime Modification",
|
||||
"returned": [
|
||||
"kn-b2a99cd7-b379-4d9b-a996-e347a02c7bad",
|
||||
"bl-a313d67b-dd6d-4e5b-a55a-03bc7bda17ae",
|
||||
"kn-8e1bfb48-33a9-45ad-8da7-e0bdaa5d34e7",
|
||||
"art-92e1837c-5919-42d0-bbb0-4d924d7b2864",
|
||||
"bl-a7a1428f-db9c-417b-8e2c-713b1f84dc1f",
|
||||
"mem-f823e835-313f-4282-b4b3-ce527ffc2f7a",
|
||||
"? ?}&?#??X\b",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"?Z?.\f?0?]P?",
|
||||
"bl-145a0985-2382-400f-a7c5-c335c5e30a72"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 2820.6,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.14285714285714285,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.14285714285714285
|
||||
},
|
||||
{
|
||||
"id": "q13",
|
||||
"category": "phrase",
|
||||
"query": "zero-knowledge encrypted backup",
|
||||
"returned": [
|
||||
"art-e495c8c5-ad95-4b64-8771-f68aa4cfcd0a",
|
||||
"kn-5584ef9c-7f9d-4d7c-a10a-4ee6bc5cf356",
|
||||
"bl-e20944e5-eb16-4ab3-a84d-111e0fc817fa",
|
||||
"bl-e20944e5-f4a6-44a0-91b1-73d04ebed120",
|
||||
"mem-47f72b5b-6e8b-4293-94f1-350197b4809a",
|
||||
"mem-a5f04e52-91f8-41d2-af27-8bf803621758",
|
||||
"7774a16c-1027-4e3b-a21e-67f1f95a4acd",
|
||||
"? ?}&?#??X\b",
|
||||
"7?e?7???\f3?",
|
||||
"deda48cd-5e1a-46cb-bd43-8016afdb3a8a"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 2609.4,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.1
|
||||
},
|
||||
{
|
||||
"id": "q14",
|
||||
"category": "paraphrase",
|
||||
"query": "the elderly relative who passed while he stayed away",
|
||||
"returned": [
|
||||
"knw-6b48dce2-f21c-452a-9db5-4e6aa61c87ca",
|
||||
"kn-82be4e41-96c5-4da3-85c0-cee10763d975",
|
||||
"mem-ea487cb4-ed67-44ce-8402-b56bb28468d4",
|
||||
"bl-2694b588-a6e3-43de-861c-fa7b0ec7e7fd",
|
||||
"bl-14883d81-f7cb-46dd-82c2-a6e6980264e5",
|
||||
"tag-dark-theme",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c",
|
||||
"? ?}&?#??X\b",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
|
||||
"art-4a99aa1a-489b-4b43-958b-25217adb1aad"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 5510.9,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q15",
|
||||
"category": "paraphrase",
|
||||
"query": "a soldier sidelined by illness who refused to quit",
|
||||
"returned": [
|
||||
"mem-0328c3cb-4550-4ce4-9284-152e832f08f6",
|
||||
"bl-07375bf9-a169-42cd-adb3-7d32b25982f0",
|
||||
"kn-57b4c5e7-40c6-4c90-bf14-71841b0081d4",
|
||||
"bl-e5635b1a-c5d0-4caa-bcc8-6a726ea43685",
|
||||
"bl-6172d035-dd94-4776-afdd-d8915f6fc375",
|
||||
"bl-5bb8dedf-8498-4a9b-acdc-31cc9c738f2a",
|
||||
"art-2f29ad36-6ee6-4a0e-8d72-0eaf7d12d3a9",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c",
|
||||
"art-80ca3d31-84dc-4502-83f4-538372b9764f",
|
||||
";??A5???"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 5444.2,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q16",
|
||||
"category": "paraphrase",
|
||||
"query": "choosing an uncomfortable fact over a pleasant fiction",
|
||||
"returned": [
|
||||
"bl-d24fcce8-2b55-426f-867a-db3958a622d3",
|
||||
"tag-phase-3",
|
||||
"tag-project-structure",
|
||||
"tag-anthropic-contrast",
|
||||
"tag-voice-training",
|
||||
"tag-ebd",
|
||||
"art-80ca3d31-84dc-4502-83f4-538372b9764f",
|
||||
"bl-9d53422d-b703-4f1d-860a-8598cb29b792",
|
||||
";??A5???",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 5056.4,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q17",
|
||||
"category": "paraphrase",
|
||||
"query": "a tight payload beats a bloated one",
|
||||
"returned": [
|
||||
"bl-fc893be3-e6b4-4ef6-93b0-d54ca5f89083",
|
||||
"bl-57c5cf6b-81a5-4558-9902-5c02981fe273",
|
||||
"tag-guilds",
|
||||
"tag-kids",
|
||||
"tag-coexistence",
|
||||
"tag-cultivated-general-intelligence",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-d7c1e0fb-fa59-46d3-b4c9-a0d1d437a491",
|
||||
";??A5???",
|
||||
"mem-cdff0c49-3ac7-4de8-89ec-92d254bd0023"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 3473.1,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q18",
|
||||
"category": "paraphrase",
|
||||
"query": "if you are able and nobody is coming the job is yours",
|
||||
"returned": [
|
||||
"knw-7902acca-604e-409b-8faf-ad85424211d0",
|
||||
"bl-bd9fb314-e9d4-4b03-aef4-534dd57a2992",
|
||||
"bl-b019ce7a-1b21-436e-812d-032f50c6c45f",
|
||||
"bl-e98cdd4c-01b5-459e-9036-3578cd5d975a",
|
||||
"bl-9ce4128a-9436-4b06-82bc-8a6faafa81e0",
|
||||
"tag-stable-diffusion",
|
||||
";??A5???",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c",
|
||||
"art-80ca3d31-84dc-4502-83f4-538372b9764f",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 4446.7,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q19",
|
||||
"category": "paraphrase",
|
||||
"query": "learning is the wealth creditors cannot seize",
|
||||
"returned": [
|
||||
"mem-e321e54e-8bb3-4596-b13d-bb093d6b149d",
|
||||
"mem-e32ba5a7-c147-4dc0-9479-b720d768eda6",
|
||||
"mem-c7a77457-478d-4eb0-a116-67205a0066a4",
|
||||
"bl-1b20e9bc-eb37-4907-8d63-e311fd61eab8",
|
||||
"bl-aa762207-920d-45ab-b2a3-2f8154d7ef9b",
|
||||
"tag-misalignment",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c",
|
||||
"? ?}&?#??X\b",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 3932.3,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q20",
|
||||
"category": "paraphrase",
|
||||
"query": "reliability proven by track record not assertion",
|
||||
"returned": [
|
||||
"kn-48a01973-a025-471d-950f-b93e6a426d82",
|
||||
"mem-23d22bc1-a097-446b-8f11-8aff099e0b76",
|
||||
"mem-6f0b2b45-90c1-4356-ac01-3daac05b09c8",
|
||||
"mem-ce5a2ffc-ad39-4728-9ac6-76fef507d5da",
|
||||
"project-Stripe_Elements__not_hosted_checkout__Custom_URL__DAG_bundle_pricing__Stripe_Connect_80_20_",
|
||||
"tag-provenance",
|
||||
"? ?}&?#??X\b",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"art-2f29ad36-6ee6-4a0e-8d72-0eaf7d12d3a9",
|
||||
"art-e495c8c5-ad95-4b64-8771-f68aa4cfcd0a"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 4836.1,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q21",
|
||||
"category": "paraphrase",
|
||||
"query": "boundaries that enable instead of confine",
|
||||
"returned": [
|
||||
"kn-79056192-7de8-486c-9565-f128439a6fcb",
|
||||
"bl-f6236350-f7b8-4f4f-a702-9eef2eb76e4b",
|
||||
"bl-7f33f1bc-99fa-4906-889f-a42375beea20",
|
||||
"mem-ef0091d8-1b65-431e-afa8-c6c4ee5779c9",
|
||||
"mem-1f32f73a-952c-41bc-96dc-8b8b70d8a7c1",
|
||||
"tag-__cultivation-metric____internal-state____dharma____evidence____novel-idea____gap-compression____values____microsoft__",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-d7c1e0fb-fa59-46d3-b4c9-a0d1d437a491",
|
||||
"art-80ca3d31-84dc-4502-83f4-538372b9764f",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 4057.4,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q22",
|
||||
"category": "paraphrase",
|
||||
"query": "what shifts tells you where to cut a system apart",
|
||||
"returned": [
|
||||
"knw-723551f5-1950-42a3-8b89-b6a06913cef0",
|
||||
"tag-identity-studio",
|
||||
"tag-finance",
|
||||
"tag-temporal",
|
||||
"tag-barkhausen",
|
||||
"tag-ilogger",
|
||||
"tag-design-first",
|
||||
";??A5???",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c",
|
||||
"? ?}&?#??X\b"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 5098.3,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q23",
|
||||
"category": "paraphrase",
|
||||
"query": "a mind that compounds instead of resetting each day",
|
||||
"returned": [
|
||||
"project-Goal_setting__alignment__scoring__cadence__Attaches_to_any_imprint_",
|
||||
"tag-performed-values",
|
||||
"tag-turing-test",
|
||||
"tag-sealed",
|
||||
"tag-part-5",
|
||||
"tag-model",
|
||||
"art-80ca3d31-84dc-4502-83f4-538372b9764f",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
|
||||
"? ?}&?#??X\b",
|
||||
";??A5???"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 4652.7,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q24",
|
||||
"category": "paraphrase",
|
||||
"query": "loved for the unedited self and not the polished exterior",
|
||||
"returned": [
|
||||
"mem-9590ba23-bddb-43e8-a571-68a263c4c364",
|
||||
"project-Imprint__leadership_development__feedback_frameworks__performance__presence_",
|
||||
"bl-a9e57bb2-00a1-4867-ab59-5d9271134b50",
|
||||
"bl-c7793c4a-7630-47fc-a462-d23059087e80",
|
||||
"tag-gateway_platform_neuron-technologies_go_proxy_llm",
|
||||
"tag-fornax",
|
||||
";??A5???",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
|
||||
"art-80ca3d31-84dc-4502-83f4-538372b9764f"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 4653.5,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q25",
|
||||
"category": "paraphrase",
|
||||
"query": "cheerfulness you arrive at instead of assuming",
|
||||
"returned": [
|
||||
"bl-7a13527b-3e0c-418a-9f37-88fd2152e5ce",
|
||||
"bl-3f57bc69-7285-4f4a-a861-2de52efca058",
|
||||
"bl-5e390b10-8753-4f25-a1a5-b5dbbb002cbf",
|
||||
"tag-ats",
|
||||
"tag-data-model",
|
||||
"tag-aggregation",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c",
|
||||
"art-80ca3d31-84dc-4502-83f4-538372b9764f",
|
||||
";??A5???",
|
||||
"? ?}&?#??X\b"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 4272.7,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q26",
|
||||
"category": "paraphrase",
|
||||
"query": "a childhood offering no solid foundation to inherit",
|
||||
"returned": [
|
||||
"tag-memory-model",
|
||||
"tag-storage",
|
||||
"tag-ga4",
|
||||
"tag-potions",
|
||||
"tag-resonance",
|
||||
"tag-neuron",
|
||||
"? ?}&?#??X\b",
|
||||
";??A5???",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 4541.0,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q27",
|
||||
"category": "associative",
|
||||
"query": "Grandma Lucas stroke February 2006 goodbye window",
|
||||
"returned": [
|
||||
"mem-927f41ab-8ede-4f58-acb3-995db16ac775",
|
||||
"mem-dbe80bc2-c602-46b0-b4ea-dd222e52bcde",
|
||||
"mem-82158b02-a180-435d-84f0-0b7ce37511b4",
|
||||
"bl-33ecccc2-e37f-43db-91b3-c2a86f08aaac",
|
||||
"bl-4476e856-c567-4b49-8ff7-d7dca3e5715e",
|
||||
"tag-upload-window",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
|
||||
"kn-a99cefe3-5e83-4050-98d8-6c69f57c7c71",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 4883.9,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q28",
|
||||
"category": "associative",
|
||||
"query": "Marines hernia sepsis medical ward",
|
||||
"returned": [
|
||||
"knw-920c891f-bb8c-48c4-9afc-018ef12dcdc4",
|
||||
"knw-08559f5c-2306-4220-a146-398c74f1643c",
|
||||
"mem-434be7c8-88cb-4039-b79a-1da4ac4de783",
|
||||
"mem-481c769c-68cc-45c7-bc37-c0d9778fa648",
|
||||
"bl-5b17bd3b-0c41-46cb-a710-6fa4429692ff",
|
||||
"bl-9d8f3c5b-4bac-41ce-8ac4-44733f99d6c8",
|
||||
"bl-33ecccc2-e37f-43db-91b3-c2a86f08aaac",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
|
||||
"kn-58874a74-b96f-4883-9e08-45707f4bd3ee",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 3237.6,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q29",
|
||||
"category": "associative",
|
||||
"query": "Sarah Bishop Dyer trailer performance",
|
||||
"returned": [
|
||||
"kn-58874a74-b96f-4883-9e08-45707f4bd3ee",
|
||||
"kn-f8974b26-78a6-4aad-b893-19a73b20013d",
|
||||
"kn-eb1c6d99-d603-4f33-be9a-c63a178690c6",
|
||||
"mem-a3124d5b-2f50-477f-8bb5-06879f5a496c",
|
||||
"bl-7fa1b1a8-b80a-4f28-b162-bfe73765b4f8",
|
||||
"mem-89c02aae-d3ca-43f9-9e5d-eb369896276c",
|
||||
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
|
||||
"? ?}&?#??X\b",
|
||||
"art-4a99aa1a-489b-4b43-958b-25217adb1aad",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 2457.7,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q30",
|
||||
"category": "associative",
|
||||
"query": "Swarm Architecture containment lateral worker",
|
||||
"returned": [
|
||||
"mem-265a7107-73b3-4410-9aff-43787d5f473b",
|
||||
"mem-9d1bf963-1b40-4588-bdb3-0432646cc623",
|
||||
"mem-46780047-63a0-4a86-a16b-638b72a7fb8d",
|
||||
"mem-3987d374-3c48-4e8e-b06d-0c363f55ed9c",
|
||||
"bl-e0a0df72-de6e-46ab-800b-e1e3e8dfc387",
|
||||
"tag-__patents____swarm____claim-language____prior-art____filing__",
|
||||
"? ?}&?#??X\b",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"7?e?7???\f3?",
|
||||
"?of?7???"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 2640.4,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q31",
|
||||
"category": "associative",
|
||||
"query": "hope won inside the narrative preface",
|
||||
"returned": [
|
||||
"kn-dca14c4c-4859-47b0-996e-33964ba61a87",
|
||||
"bl-dc8c7e02-eb37-48ae-a6f8-9b512803ae16",
|
||||
"mem-8d1bafe6-209c-456c-9a25-9a927bc5a16d",
|
||||
"bl-0de4e61b-6562-49e5-b7df-ebb809a01723",
|
||||
"bl-8ef1ba6b-3fa0-4dbd-98c5-31665e5694a1",
|
||||
"mem-22f5f665-3ad2-4063-88b0-915849a795f5",
|
||||
"? ?}&?#??X\b",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
|
||||
"?Q??m?;��`'",
|
||||
"R^??m?;��?'"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 3705.7,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q32",
|
||||
"category": "associative",
|
||||
"query": "man of the house six years old expectation",
|
||||
"returned": [
|
||||
"kn-eb1b9e18-3dc6-4b9b-9cc6-86e0ae6b6be8",
|
||||
"mem-394cc9e8-049b-45bc-a380-66314f14e367",
|
||||
"bl-ffa22d7e-42a9-4bd2-a428-1d2df243ac93",
|
||||
"bl-4a6746e8-191f-48fc-8bfb-c4dc73b80bcd",
|
||||
"tag-command-pattern",
|
||||
"tag-withholding",
|
||||
"tag-offline",
|
||||
"art-80ca3d31-84dc-4502-83f4-538372b9764f",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c",
|
||||
"? ?}&?#??X\b"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 4223.3,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q33",
|
||||
"category": "nonsense",
|
||||
"query": "zqxjvw plimforth grebulon",
|
||||
"returned": [],
|
||||
"n_returned": 0,
|
||||
"latency_ms": 1333.9,
|
||||
"error": null,
|
||||
"clean": true,
|
||||
"false_positives": 0
|
||||
},
|
||||
{
|
||||
"id": "q34",
|
||||
"category": "nonsense",
|
||||
"query": "flarnbistle quommetry",
|
||||
"returned": [],
|
||||
"n_returned": 0,
|
||||
"latency_ms": 880.7,
|
||||
"error": null,
|
||||
"clean": true,
|
||||
"false_positives": 0
|
||||
},
|
||||
{
|
||||
"id": "q35",
|
||||
"category": "nonsense",
|
||||
"query": "xxqzzt vurblenacht throom",
|
||||
"returned": [
|
||||
"kn-333542cb-6dab-4662-9725-bf7440d28bf7",
|
||||
"? ?}&?#??X\b",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325",
|
||||
"kn-66a21179-2adc-4b19-a109-880cf4674d7d",
|
||||
"bl-4476e856-c567-4b49-8ff7-d7dca3e5715e",
|
||||
"art-4a99aa1a-489b-4b43-958b-25217adb1aad",
|
||||
"knw-920c891f-bb8c-48c4-9afc-018ef12dcdc4"
|
||||
],
|
||||
"n_returned": 8,
|
||||
"latency_ms": 1452.7,
|
||||
"error": null,
|
||||
"clean": false,
|
||||
"false_positives": 8
|
||||
},
|
||||
{
|
||||
"id": "q36",
|
||||
"category": "superseded",
|
||||
"query": "is the self-improvement architecture called DARMA or DHARMA",
|
||||
"returned": [
|
||||
"ctx-e5427d7d",
|
||||
"mem-37b57f52-a29a-42cf-a07a-3c5f8a3598dd",
|
||||
"project-worldweaver",
|
||||
"tag-__kotlin____internal-state____pre-reasoning____post-reasoning____compression-ratio____dharma____cultivation__",
|
||||
"tag-import",
|
||||
"tag-__cgi____dharma____cultivation____five-primitives____seed-artifact____agi____intelligence____whitepaper____patent__",
|
||||
"art-80ca3d31-84dc-4502-83f4-538372b9764f",
|
||||
"? ?}&?#??X\b",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 3843.5,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0,
|
||||
"outranks": false,
|
||||
"rank_correct": null,
|
||||
"rank_stale": null
|
||||
},
|
||||
{
|
||||
"id": "q37",
|
||||
"category": "superseded",
|
||||
"query": "how many provisional patents does Will actually have",
|
||||
"returned": [
|
||||
"mem-bfe0fafd-2750-4fdc-b773-04e878b3b23f",
|
||||
"art-7bdaff30-5af9-4f0a-93b1-751686f9de3d",
|
||||
"mem-cf07910d-4676-4384-ab97-9cad946cd0b9",
|
||||
"mem-f9da4b43-3724-4bc8-92f8-6f237c89dc4d",
|
||||
"project-Convert_UTC_timestamps_to_Central_time_when_displaying_to_Will__Never_surface_raw_UTC_",
|
||||
"mem-32203649-3213-4d6d-86fd-3d657ac70d77",
|
||||
";??A5???",
|
||||
"? ?}&?#??X\b",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c",
|
||||
"art-80ca3d31-84dc-4502-83f4-538372b9764f"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 5264.0,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0,
|
||||
"outranks": false,
|
||||
"rank_correct": null,
|
||||
"rank_stale": null
|
||||
},
|
||||
{
|
||||
"id": "q38",
|
||||
"category": "superseded",
|
||||
"query": "is MCP still the live integration layer",
|
||||
"returned": [
|
||||
"project-Define_Iris_as_separate_public_brand__Uncensored_but_principled__Consumer_face_while_Neuron_runs_enterprise_",
|
||||
"project-Imprint__discovery__objection_handling__deal_strategy__pipeline__closing_",
|
||||
"bl-8116da7a-b039-4e08-b8d0-c1c7861f9766",
|
||||
"tag-enterprise",
|
||||
"tag-divisors",
|
||||
"tag-distressed-property",
|
||||
"? ?}&?#??X\b",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325",
|
||||
"???Ͼd??W\b?",
|
||||
"kn-d7c1e0fb-fa59-46d3-b4c9-a0d1d437a491"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 3022.7,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0,
|
||||
"outranks": false,
|
||||
"rank_correct": null,
|
||||
"rank_stale": null
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,942 @@
|
||||
{
|
||||
"label": "act-r3",
|
||||
"soul_binary": "/private/tmp/claude-501/-Users-timlingo/82369039-a20e-4b5a-8a5e-28234a57b996/scratchpad/soul-act",
|
||||
"soul_md5": "77722f5a9f49494bf735c2a4be1b5dc4",
|
||||
"corpus": "/Users/timlingo/neuron-memory-backups/snapshot-pre-repair-20260806.json",
|
||||
"corpus_nodes": 78768,
|
||||
"corpus_edges": 14214,
|
||||
"gold_set": "/Users/timlingo/Development/neuron-technologies/_wt-eval/tools/retrieval-eval/gold_set.json",
|
||||
"limit": 10,
|
||||
"port": 7903,
|
||||
"wall_clock_s": 112.0,
|
||||
"child_pid": 78802,
|
||||
"child_confirmed_dead": true,
|
||||
"aggregate": {
|
||||
"n_queries": 38,
|
||||
"n_scored": 35,
|
||||
"hit@5": 0.2571428571428571,
|
||||
"recall@5": 0.19291383219954647,
|
||||
"recall@10": 0.244812925170068,
|
||||
"precision@5": 0.08,
|
||||
"mrr@10": 0.266031746031746,
|
||||
"nonsense_clean": "2/3",
|
||||
"superseded_outranks": "0/3",
|
||||
"latency_ms_p50": 3220.9,
|
||||
"latency_ms_p95": 4840.2,
|
||||
"latency_ms_max": 5073.6,
|
||||
"errors": 0,
|
||||
"by_category": {
|
||||
"associative": {
|
||||
"n": 6,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
"exact_rare": {
|
||||
"n": 6,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
"nonsense": {
|
||||
"n": 3,
|
||||
"clean": 2,
|
||||
"avg_false_positives": 2.6666666666666665
|
||||
},
|
||||
"paraphrase": {
|
||||
"n": 13,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
"phrase": {
|
||||
"n": 7,
|
||||
"hit@5": 0.42857142857142855,
|
||||
"recall@5": 0.10742630385487528,
|
||||
"recall@10": 0.366921768707483,
|
||||
"mrr@10": 0.47301587301587306
|
||||
},
|
||||
"superseded": {
|
||||
"n": 3,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"mrr@10": 0.0,
|
||||
"outranks": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"rows": [
|
||||
{
|
||||
"id": "q01",
|
||||
"category": "exact_rare",
|
||||
"query": "unjailbreakable",
|
||||
"returned": [
|
||||
"mem-7f61beb4-271c-4feb-9f6e-1c9c837a6226"
|
||||
],
|
||||
"n_returned": 1,
|
||||
"latency_ms": 471.2,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q02",
|
||||
"category": "exact_rare",
|
||||
"query": "engram-migrate",
|
||||
"returned": [
|
||||
"mem-6fdf6545-5e1a-43a9-8bdc-d2cd248146a5"
|
||||
],
|
||||
"n_returned": 1,
|
||||
"latency_ms": 548.8,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q03",
|
||||
"category": "exact_rare",
|
||||
"query": "cartabandonedevent",
|
||||
"returned": [
|
||||
"mem-1ba7c67d-85b9-4c2e-9fe2-39f8b0477091"
|
||||
],
|
||||
"n_returned": 1,
|
||||
"latency_ms": 470.3,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q04",
|
||||
"category": "exact_rare",
|
||||
"query": "pre-apprenticeship",
|
||||
"returned": [
|
||||
"mem-89c02aae-d3ca-43f9-9e5d-eb369896276c"
|
||||
],
|
||||
"n_returned": 1,
|
||||
"latency_ms": 476.3,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q05",
|
||||
"category": "exact_rare",
|
||||
"query": "inferencenodemanager",
|
||||
"returned": [
|
||||
"mem-73969486-143f-4431-b5e6-6845d1cc9848"
|
||||
],
|
||||
"n_returned": 1,
|
||||
"latency_ms": 515.9,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q06",
|
||||
"category": "exact_rare",
|
||||
"query": "clear-eyed",
|
||||
"returned": [
|
||||
"knw-c72597c5-c23d-4c08-8e9e-996dadf26a99"
|
||||
],
|
||||
"n_returned": 1,
|
||||
"latency_ms": 458.7,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q07",
|
||||
"category": "phrase",
|
||||
"query": "patterns not returns",
|
||||
"returned": [
|
||||
"knw-d357b6bb-ad8a-4791-b516-426aea45fa5b",
|
||||
"kn-69fd6e83-7718-4824-8d66-f49d8954e224",
|
||||
"kn-d97920d0-1649-4223-9508-c0bb621e7fc0",
|
||||
"kn-5584ef9c-7f9d-4d7c-a10a-4ee6bc5cf356",
|
||||
"kn-57b4c5e7-40c6-4c90-bf14-71841b0081d4",
|
||||
"kn-c3d9d063-8c5d-45aa-900c-550914b2ff6d",
|
||||
"kn-82be4e41-96c5-4da3-85c0-cee10763d975",
|
||||
"bl-76e878aa-e1fe-468c-bf9c-854097cb7e0b",
|
||||
"art-9887867c-2e21-47c3-9f96-c2dfe5bd4cc1",
|
||||
"bl-31abf75b-998f-4a4f-a6dd-8204119e0451"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1595.1,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q08",
|
||||
"category": "phrase",
|
||||
"query": "thirty moves",
|
||||
"returned": [
|
||||
"knw-7902acca-604e-409b-8faf-ad85424211d0",
|
||||
"knw-2c46cfb4-6d4e-4822-8a1a-7d743c1e4329",
|
||||
"bl-80720fdf-7ce7-4d28-aff8-21028d3a8cfb",
|
||||
"art-2f29ad36-6ee6-4a0e-8d72-0eaf7d12d3a9",
|
||||
"knw-ed33e669-0790-44cb-a036-958d605c6fea",
|
||||
"kn-6061318f-046b-4935-907d-8eafdce14930",
|
||||
"015644f5-8194-4af0-800d-dd4a0cd71396",
|
||||
"art-80ca3d31-84dc-4502-83f4-538372b9764f",
|
||||
"?Z?.\f?0?]P?",
|
||||
"?Q??m?;��`'"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 927.5,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 0.125,
|
||||
"recall@10": 0.1875,
|
||||
"precision@5": 0.4,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q09",
|
||||
"category": "phrase",
|
||||
"query": "Grandma Lucas",
|
||||
"returned": [
|
||||
"kn-a99cefe3-5e83-4050-98d8-6c69f57c7c71",
|
||||
"? ?}&?#??X\b",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c",
|
||||
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
|
||||
"766de879-f9d0-4a07-b6df-b43ee13763d8",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325"
|
||||
],
|
||||
"n_returned": 6,
|
||||
"latency_ms": 963.9,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 0.5555555555555556,
|
||||
"recall@10": 0.5555555555555556,
|
||||
"precision@5": 1.0,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q10",
|
||||
"category": "phrase",
|
||||
"query": "Directed Harmonic",
|
||||
"returned": [
|
||||
"knw-e24d6339-5ff3-4bed-ba53-707ffd0dc70a",
|
||||
"art-e495c8c5-ad95-4b64-8771-f68aa4cfcd0a",
|
||||
"bl-7aebe936-ac55-4f35-8932-adc5224ff854",
|
||||
"knw-b046991d-5992-4ac4-b854-7d3ac273832c",
|
||||
"mem-ab34c2f7-3243-424b-affa-25555f6cf9cc",
|
||||
"bl-9d53422d-b703-4f1d-860a-8598cb29b792",
|
||||
"bl-455a08cf-5831-4fdb-b42c-b952f2feafb9",
|
||||
"? ?}&?#??X\b",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"mem-7eeacad7-d7c2-4c2b-8348-19a59aa6dbaf"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 927.5,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.1111111111111111,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.1
|
||||
},
|
||||
{
|
||||
"id": "q11",
|
||||
"category": "phrase",
|
||||
"query": "Sarah Bishop",
|
||||
"returned": [
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
|
||||
"art-4a99aa1a-489b-4b43-958b-25217adb1aad",
|
||||
"art-8dbceb06-431a-416d-a723-e8c75d595154",
|
||||
"mem-a3124d5b-2f50-477f-8bb5-06879f5a496c",
|
||||
"art-94fae615-7cd5-4695-b968-977101b06a51",
|
||||
"mem-a9a9ce95-0d64-46eb-9db8-ff81d78ade35",
|
||||
"mem-57164d5f-baf0-4149-957a-379a4e255d1a",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
|
||||
"art-2fabd873-d787-49cb-ad30-d4ed9fcff8ef"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 937.5,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.5,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.1111111111111111
|
||||
},
|
||||
{
|
||||
"id": "q12",
|
||||
"category": "phrase",
|
||||
"query": "Directed Autonomous Runtime Modification",
|
||||
"returned": [
|
||||
"bl-5b17bd3b-0c41-46cb-a710-6fa4429692ff",
|
||||
"kn-b2a99cd7-b379-4d9b-a996-e347a02c7bad",
|
||||
"bl-a313d67b-dd6d-4e5b-a55a-03bc7bda17ae",
|
||||
"kn-8e1bfb48-33a9-45ad-8da7-e0bdaa5d34e7",
|
||||
"mem-cdff0c49-3ac7-4de8-89ec-92d254bd0023",
|
||||
"bl-a7a1428f-db9c-417b-8e2c-713b1f84dc1f",
|
||||
"? ?}&?#??X\b",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"?Z?.\f?0?]P?",
|
||||
"bl-145a0985-2382-400f-a7c5-c335c5e30a72"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 2451.5,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 0.07142857142857142,
|
||||
"recall@10": 0.21428571428571427,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q13",
|
||||
"category": "phrase",
|
||||
"query": "zero-knowledge encrypted backup",
|
||||
"returned": [
|
||||
"mem-7cd90611-88a3-423d-a38a-0db2812952fa",
|
||||
"bl-e20944e5-f4a6-44a0-91b1-73d04ebed120",
|
||||
"mem-64cf3728-674c-404b-965a-b8f8d38bb7bb",
|
||||
"mem-47f72b5b-6e8b-4293-94f1-350197b4809a",
|
||||
"mem-e612f0aa-c2f2-4ee3-bbc7-af2dc826233b",
|
||||
"mem-a5f04e52-91f8-41d2-af27-8bf803621758",
|
||||
"7774a16c-1027-4e3b-a21e-67f1f95a4acd",
|
||||
"? ?}&?#??X\b",
|
||||
"7?e?7???\f3?",
|
||||
"deda48cd-5e1a-46cb-bd43-8016afdb3a8a"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 2042.9,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.1
|
||||
},
|
||||
{
|
||||
"id": "q14",
|
||||
"category": "paraphrase",
|
||||
"query": "the elderly relative who passed while he stayed away",
|
||||
"returned": [
|
||||
"knw-6b48dce2-f21c-452a-9db5-4e6aa61c87ca",
|
||||
"mem-ea487cb4-ed67-44ce-8402-b56bb28468d4",
|
||||
"art-c71aef51-026f-4d63-80e9-2a0ec0dc3865",
|
||||
"bl-2dd8aaa1-b0de-4eac-b3c5-78951d240b60",
|
||||
"bl-2694b588-a6e3-43de-861c-fa7b0ec7e7fd",
|
||||
"bl-14883d81-f7cb-46dd-82c2-a6e6980264e5",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c",
|
||||
"? ?}&?#??X\b",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
|
||||
"art-4a99aa1a-489b-4b43-958b-25217adb1aad"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 4698.2,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q15",
|
||||
"category": "paraphrase",
|
||||
"query": "a soldier sidelined by illness who refused to quit",
|
||||
"returned": [
|
||||
"bl-fd047ce9-ae21-4b3e-b3ab-ece0c9592f7f",
|
||||
"kn-57b4c5e7-40c6-4c90-bf14-71841b0081d4",
|
||||
"bl-9ce4128a-9436-4b06-82bc-8a6faafa81e0",
|
||||
"bl-6172d035-dd94-4776-afdd-d8915f6fc375",
|
||||
"bl-5bb8dedf-8498-4a9b-acdc-31cc9c738f2a",
|
||||
"tag-cultivated-general-intelligence",
|
||||
"art-2fabd873-d787-49cb-ad30-d4ed9fcff8ef",
|
||||
"art-2f29ad36-6ee6-4a0e-8d72-0eaf7d12d3a9",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c",
|
||||
"art-80ca3d31-84dc-4502-83f4-538372b9764f"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 5073.6,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q16",
|
||||
"category": "paraphrase",
|
||||
"query": "choosing an uncomfortable fact over a pleasant fiction",
|
||||
"returned": [
|
||||
"bl-e5635b1a-c5d0-4caa-bcc8-6a726ea43685",
|
||||
"bl-fc893be3-e6b4-4ef6-93b0-d54ca5f89083",
|
||||
"tag-project-structure",
|
||||
"tag-anthropic-contrast",
|
||||
"tag-voice-training",
|
||||
"tag-ebd",
|
||||
"art-80ca3d31-84dc-4502-83f4-538372b9764f",
|
||||
"015644f5-8194-4af0-800d-dd4a0cd71396",
|
||||
"art-2fabd873-d787-49cb-ad30-d4ed9fcff8ef",
|
||||
"bl-9d53422d-b703-4f1d-860a-8598cb29b792"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 4117.3,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q17",
|
||||
"category": "paraphrase",
|
||||
"query": "a tight payload beats a bloated one",
|
||||
"returned": [
|
||||
"bl-d24fcce8-2b55-426f-867a-db3958a622d3",
|
||||
"tag-phase-3",
|
||||
"bl-57c5cf6b-81a5-4558-9902-5c02981fe273",
|
||||
"tag-guilds",
|
||||
"tag-kids",
|
||||
"tag-coexistence",
|
||||
"015644f5-8194-4af0-800d-dd4a0cd71396",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-d7c1e0fb-fa59-46d3-b4c9-a0d1d437a491",
|
||||
"mem-cdff0c49-3ac7-4de8-89ec-92d254bd0023"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 3254.5,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q18",
|
||||
"category": "paraphrase",
|
||||
"query": "if you are able and nobody is coming the job is yours",
|
||||
"returned": [
|
||||
"bl-07375bf9-a169-42cd-adb3-7d32b25982f0",
|
||||
"mem-0328c3cb-4550-4ce4-9284-152e832f08f6",
|
||||
"knw-7902acca-604e-409b-8faf-ad85424211d0",
|
||||
"bl-bd9fb314-e9d4-4b03-aef4-534dd57a2992",
|
||||
"bl-e98cdd4c-01b5-459e-9036-3578cd5d975a",
|
||||
"tag-stable-diffusion",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c",
|
||||
"art-80ca3d31-84dc-4502-83f4-538372b9764f",
|
||||
"015644f5-8194-4af0-800d-dd4a0cd71396",
|
||||
"art-2fabd873-d787-49cb-ad30-d4ed9fcff8ef"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 4081.1,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q19",
|
||||
"category": "paraphrase",
|
||||
"query": "learning is the wealth creditors cannot seize",
|
||||
"returned": [
|
||||
"mem-e32ba5a7-c147-4dc0-9479-b720d768eda6",
|
||||
"bl-b019ce7a-1b21-436e-812d-032f50c6c45f",
|
||||
"mem-c7a77457-478d-4eb0-a116-67205a0066a4",
|
||||
"bl-1b20e9bc-eb37-4907-8d63-e311fd61eab8",
|
||||
"bl-aa762207-920d-45ab-b2a3-2f8154d7ef9b",
|
||||
"tag-misalignment",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c",
|
||||
"015644f5-8194-4af0-800d-dd4a0cd71396",
|
||||
"art-2fabd873-d787-49cb-ad30-d4ed9fcff8ef",
|
||||
"? ?}&?#??X\b"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 3687.3,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q20",
|
||||
"category": "paraphrase",
|
||||
"query": "reliability proven by track record not assertion",
|
||||
"returned": [
|
||||
"kn-48a01973-a025-471d-950f-b93e6a426d82",
|
||||
"mem-23d22bc1-a097-446b-8f11-8aff099e0b76",
|
||||
"mem-6f0b2b45-90c1-4356-ac01-3daac05b09c8",
|
||||
"mem-ce5a2ffc-ad39-4728-9ac6-76fef507d5da",
|
||||
"project-Stripe_Elements__not_hosted_checkout__Custom_URL__DAG_bundle_pricing__Stripe_Connect_80_20_",
|
||||
"mem-e321e54e-8bb3-4596-b13d-bb093d6b149d",
|
||||
"? ?}&?#??X\b",
|
||||
"art-2fabd873-d787-49cb-ad30-d4ed9fcff8ef",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"art-2f29ad36-6ee6-4a0e-8d72-0eaf7d12d3a9"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 4659.8,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q21",
|
||||
"category": "paraphrase",
|
||||
"query": "boundaries that enable instead of confine",
|
||||
"returned": [
|
||||
"kn-79056192-7de8-486c-9565-f128439a6fcb",
|
||||
"bl-f6236350-f7b8-4f4f-a702-9eef2eb76e4b",
|
||||
"bl-7f33f1bc-99fa-4906-889f-a42375beea20",
|
||||
"mem-37b57f52-a29a-42cf-a07a-3c5f8a3598dd",
|
||||
"mem-1f32f73a-952c-41bc-96dc-8b8b70d8a7c1",
|
||||
"tag-__cultivation-metric____internal-state____dharma____evidence____novel-idea____gap-compression____values____microsoft__",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-d7c1e0fb-fa59-46d3-b4c9-a0d1d437a491",
|
||||
"art-80ca3d31-84dc-4502-83f4-538372b9764f",
|
||||
"knw-b046991d-5992-4ac4-b854-7d3ac273832c"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 3960.8,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q22",
|
||||
"category": "paraphrase",
|
||||
"query": "what shifts tells you where to cut a system apart",
|
||||
"returned": [
|
||||
"knw-723551f5-1950-42a3-8b89-b6a06913cef0",
|
||||
"tag-identity-studio",
|
||||
"tag-finance",
|
||||
"tag-temporal",
|
||||
"tag-barkhausen",
|
||||
"tag-ilogger",
|
||||
"tag-design-first",
|
||||
"015644f5-8194-4af0-800d-dd4a0cd71396",
|
||||
"art-2fabd873-d787-49cb-ad30-d4ed9fcff8ef",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 4840.2,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q23",
|
||||
"category": "paraphrase",
|
||||
"query": "a mind that compounds instead of resetting each day",
|
||||
"returned": [
|
||||
"project-Goal_setting__alignment__scoring__cadence__Attaches_to_any_imprint_",
|
||||
"tag-performed-values",
|
||||
"tag-turing-test",
|
||||
"tag-sealed",
|
||||
"tag-part-5",
|
||||
"tag-model",
|
||||
"art-80ca3d31-84dc-4502-83f4-538372b9764f",
|
||||
"015644f5-8194-4af0-800d-dd4a0cd71396",
|
||||
"art-2fabd873-d787-49cb-ad30-d4ed9fcff8ef",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 4493.2,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q24",
|
||||
"category": "paraphrase",
|
||||
"query": "loved for the unedited self and not the polished exterior",
|
||||
"returned": [
|
||||
"mem-9590ba23-bddb-43e8-a571-68a263c4c364",
|
||||
"project-Imprint__leadership_development__feedback_frameworks__performance__presence_",
|
||||
"bl-a9e57bb2-00a1-4867-ab59-5d9271134b50",
|
||||
"bl-c7793c4a-7630-47fc-a462-d23059087e80",
|
||||
"tag-gateway_platform_neuron-technologies_go_proxy_llm",
|
||||
"tag-fornax",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
|
||||
"mem-ab34c2f7-3243-424b-affa-25555f6cf9cc",
|
||||
"art-80ca3d31-84dc-4502-83f4-538372b9764f"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 4509.0,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q25",
|
||||
"category": "paraphrase",
|
||||
"query": "cheerfulness you arrive at instead of assuming",
|
||||
"returned": [
|
||||
"bl-7a13527b-3e0c-418a-9f37-88fd2152e5ce",
|
||||
"bl-3f57bc69-7285-4f4a-a861-2de52efca058",
|
||||
"bl-5e390b10-8753-4f25-a1a5-b5dbbb002cbf",
|
||||
"tag-ats",
|
||||
"tag-data-model",
|
||||
"tag-aggregation",
|
||||
"015644f5-8194-4af0-800d-dd4a0cd71396",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c",
|
||||
"art-80ca3d31-84dc-4502-83f4-538372b9764f",
|
||||
"art-2fabd873-d787-49cb-ad30-d4ed9fcff8ef"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 3624.6,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q26",
|
||||
"category": "paraphrase",
|
||||
"query": "a childhood offering no solid foundation to inherit",
|
||||
"returned": [
|
||||
"tag-memory-model",
|
||||
"tag-storage",
|
||||
"tag-ga4",
|
||||
"tag-potions",
|
||||
"tag-resonance",
|
||||
"tag-neuron",
|
||||
"? ?}&?#??X\b",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 4093.9,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q27",
|
||||
"category": "associative",
|
||||
"query": "Grandma Lucas stroke February 2006 goodbye window",
|
||||
"returned": [
|
||||
"kn-f8974b26-78a6-4aad-b893-19a73b20013d",
|
||||
"mem-927f41ab-8ede-4f58-acb3-995db16ac775",
|
||||
"mem-82158b02-a180-435d-84f0-0b7ce37511b4",
|
||||
"bl-33ecccc2-e37f-43db-91b3-c2a86f08aaac",
|
||||
"bl-4476e856-c567-4b49-8ff7-d7dca3e5715e",
|
||||
"tag-upload-window",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
|
||||
"kn-a99cefe3-5e83-4050-98d8-6c69f57c7c71",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 4235.1,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q28",
|
||||
"category": "associative",
|
||||
"query": "Marines hernia sepsis medical ward",
|
||||
"returned": [
|
||||
"knw-920c891f-bb8c-48c4-9afc-018ef12dcdc4",
|
||||
"mem-0f31141d-3ac5-44b2-9942-be7e4e6feb79",
|
||||
"knw-08559f5c-2306-4220-a146-398c74f1643c",
|
||||
"mem-434be7c8-88cb-4039-b79a-1da4ac4de783",
|
||||
"mem-481c769c-68cc-45c7-bc37-c0d9778fa648",
|
||||
"bl-9d8f3c5b-4bac-41ce-8ac4-44733f99d6c8",
|
||||
"bl-33ecccc2-e37f-43db-91b3-c2a86f08aaac",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
|
||||
"kn-58874a74-b96f-4883-9e08-45707f4bd3ee",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 3220.9,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q29",
|
||||
"category": "associative",
|
||||
"query": "Sarah Bishop Dyer trailer performance",
|
||||
"returned": [
|
||||
"kn-58874a74-b96f-4883-9e08-45707f4bd3ee",
|
||||
"kn-eb1c6d99-d603-4f33-be9a-c63a178690c6",
|
||||
"mem-5e7f6ddd-c818-4ad3-b564-54ae278e9976",
|
||||
"bl-7fa1b1a8-b80a-4f28-b162-bfe73765b4f8",
|
||||
"mem-89c02aae-d3ca-43f9-9e5d-eb369896276c",
|
||||
"tag-sarah",
|
||||
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
|
||||
"? ?}&?#??X\b",
|
||||
"art-4a99aa1a-489b-4b43-958b-25217adb1aad",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 2336.6,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q30",
|
||||
"category": "associative",
|
||||
"query": "Swarm Architecture containment lateral worker",
|
||||
"returned": [
|
||||
"mem-265a7107-73b3-4410-9aff-43787d5f473b",
|
||||
"mem-9d1bf963-1b40-4588-bdb3-0432646cc623",
|
||||
"mem-46780047-63a0-4a86-a16b-638b72a7fb8d",
|
||||
"mem-3987d374-3c48-4e8e-b06d-0c363f55ed9c",
|
||||
"bl-e0a0df72-de6e-46ab-800b-e1e3e8dfc387",
|
||||
"tag-__patents____swarm____claim-language____prior-art____filing__",
|
||||
"mem-ab34c2f7-3243-424b-affa-25555f6cf9cc",
|
||||
"? ?}&?#??X\b",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"7?e?7???\f3?"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 2348.0,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q31",
|
||||
"category": "associative",
|
||||
"query": "hope won inside the narrative preface",
|
||||
"returned": [
|
||||
"kn-dca14c4c-4859-47b0-996e-33964ba61a87",
|
||||
"bl-e148d23c-24e8-4122-9915-d1c11f22052f",
|
||||
"bl-dc8c7e02-eb37-48ae-a6f8-9b512803ae16",
|
||||
"mem-8d1bafe6-209c-456c-9a25-9a927bc5a16d",
|
||||
"mem-22f5f665-3ad2-4063-88b0-915849a795f5",
|
||||
"tag-dark-theme",
|
||||
"? ?}&?#??X\b",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
|
||||
"?Q??m?;��`'",
|
||||
"R^??m?;��?'"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 3511.5,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q32",
|
||||
"category": "associative",
|
||||
"query": "man of the house six years old expectation",
|
||||
"returned": [
|
||||
"kn-eb1b9e18-3dc6-4b9b-9cc6-86e0ae6b6be8",
|
||||
"bl-ffa22d7e-42a9-4bd2-a428-1d2df243ac93",
|
||||
"mem-ef0091d8-1b65-431e-afa8-c6c4ee5779c9",
|
||||
"bl-452a4710-3d2b-4e0f-9413-49a66423bc9a",
|
||||
"bl-4a6746e8-191f-48fc-8bfb-c4dc73b80bcd",
|
||||
"tag-withholding",
|
||||
"tag-offline",
|
||||
"art-80ca3d31-84dc-4502-83f4-538372b9764f",
|
||||
"art-2fabd873-d787-49cb-ad30-d4ed9fcff8ef",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 4160.2,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q33",
|
||||
"category": "nonsense",
|
||||
"query": "zqxjvw plimforth grebulon",
|
||||
"returned": [],
|
||||
"n_returned": 0,
|
||||
"latency_ms": 1318.6,
|
||||
"error": null,
|
||||
"clean": true,
|
||||
"false_positives": 0
|
||||
},
|
||||
{
|
||||
"id": "q34",
|
||||
"category": "nonsense",
|
||||
"query": "flarnbistle quommetry",
|
||||
"returned": [],
|
||||
"n_returned": 0,
|
||||
"latency_ms": 875.7,
|
||||
"error": null,
|
||||
"clean": true,
|
||||
"false_positives": 0
|
||||
},
|
||||
{
|
||||
"id": "q35",
|
||||
"category": "nonsense",
|
||||
"query": "xxqzzt vurblenacht throom",
|
||||
"returned": [
|
||||
"kn-333542cb-6dab-4662-9725-bf7440d28bf7",
|
||||
"? ?}&?#??X\b",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325",
|
||||
"kn-66a21179-2adc-4b19-a109-880cf4674d7d",
|
||||
"bl-4476e856-c567-4b49-8ff7-d7dca3e5715e",
|
||||
"art-4a99aa1a-489b-4b43-958b-25217adb1aad",
|
||||
"knw-920c891f-bb8c-48c4-9afc-018ef12dcdc4"
|
||||
],
|
||||
"n_returned": 8,
|
||||
"latency_ms": 1393.4,
|
||||
"error": null,
|
||||
"clean": false,
|
||||
"false_positives": 8
|
||||
},
|
||||
{
|
||||
"id": "q36",
|
||||
"category": "superseded",
|
||||
"query": "is the self-improvement architecture called DARMA or DHARMA",
|
||||
"returned": [
|
||||
"knw-b046991d-5992-4ac4-b854-7d3ac273832c",
|
||||
"ctx-e5427d7d",
|
||||
"project-worldweaver",
|
||||
"tag-__kotlin____internal-state____pre-reasoning____post-reasoning____compression-ratio____dharma____cultivation__",
|
||||
"tag-import",
|
||||
"tag-enterprise",
|
||||
"tag-__cgi____dharma____cultivation____five-primitives____seed-artifact____agi____intelligence____whitepaper____patent__",
|
||||
"art-80ca3d31-84dc-4502-83f4-538372b9764f",
|
||||
"? ?}&?#??X\b",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 3775.0,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0,
|
||||
"outranks": false,
|
||||
"rank_correct": null,
|
||||
"rank_stale": null
|
||||
},
|
||||
{
|
||||
"id": "q37",
|
||||
"category": "superseded",
|
||||
"query": "how many provisional patents does Will actually have",
|
||||
"returned": [
|
||||
"mem-bfe0fafd-2750-4fdc-b773-04e878b3b23f",
|
||||
"art-7bdaff30-5af9-4f0a-93b1-751686f9de3d",
|
||||
"mem-cf07910d-4676-4384-ab97-9cad946cd0b9",
|
||||
"mem-f9da4b43-3724-4bc8-92f8-6f237c89dc4d",
|
||||
"project-Convert_UTC_timestamps_to_Central_time_when_displaying_to_Will__Never_surface_raw_UTC_",
|
||||
"mem-32203649-3213-4d6d-86fd-3d657ac70d77",
|
||||
"? ?}&?#??X\b",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c",
|
||||
"art-80ca3d31-84dc-4502-83f4-538372b9764f",
|
||||
"015644f5-8194-4af0-800d-dd4a0cd71396"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 4857.0,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0,
|
||||
"outranks": false,
|
||||
"rank_correct": null,
|
||||
"rank_stale": null
|
||||
},
|
||||
{
|
||||
"id": "q38",
|
||||
"category": "superseded",
|
||||
"query": "is MCP still the live integration layer",
|
||||
"returned": [
|
||||
"bl-0de4e61b-6562-49e5-b7df-ebb809a01723",
|
||||
"project-Imprint__discovery__objection_handling__deal_strategy__pipeline__closing_",
|
||||
"bl-8116da7a-b039-4e08-b8d0-c1c7861f9766",
|
||||
"bl-8ef1ba6b-3fa0-4dbd-98c5-31665e5694a1",
|
||||
"tag-divisors",
|
||||
"tag-distressed-property",
|
||||
"? ?}&?#??X\b",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325",
|
||||
"knw-b046991d-5992-4ac4-b854-7d3ac273832c",
|
||||
"???Ͼd??W\b?"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 2858.0,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0,
|
||||
"outranks": false,
|
||||
"rank_correct": null,
|
||||
"rank_stale": null
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,942 @@
|
||||
{
|
||||
"label": "act-r1",
|
||||
"soul_binary": "/private/tmp/claude-501/-Users-timlingo/82369039-a20e-4b5a-8a5e-28234a57b996/scratchpad/soul-act",
|
||||
"soul_md5": "77722f5a9f49494bf735c2a4be1b5dc4",
|
||||
"corpus": "/Users/timlingo/neuron-memory-backups/snapshot-pre-repair-20260806.json",
|
||||
"corpus_nodes": 78768,
|
||||
"corpus_edges": 14214,
|
||||
"gold_set": "/Users/timlingo/Development/neuron-technologies/_wt-eval/tools/retrieval-eval/gold_set.json",
|
||||
"limit": 10,
|
||||
"port": 7894,
|
||||
"wall_clock_s": 112.3,
|
||||
"child_pid": 78648,
|
||||
"child_confirmed_dead": true,
|
||||
"aggregate": {
|
||||
"n_queries": 38,
|
||||
"n_scored": 35,
|
||||
"hit@5": 0.22857142857142856,
|
||||
"recall@5": 0.19087301587301586,
|
||||
"recall@10": 0.24277210884353742,
|
||||
"precision@5": 0.07428571428571429,
|
||||
"mrr@10": 0.24154195011337865,
|
||||
"nonsense_clean": "2/3",
|
||||
"superseded_outranks": "0/3",
|
||||
"latency_ms_p50": 3208.8,
|
||||
"latency_ms_p95": 4851.9,
|
||||
"latency_ms_max": 5078.8,
|
||||
"errors": 0,
|
||||
"by_category": {
|
||||
"associative": {
|
||||
"n": 6,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
"exact_rare": {
|
||||
"n": 6,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
"nonsense": {
|
||||
"n": 3,
|
||||
"clean": 2,
|
||||
"avg_false_positives": 2.6666666666666665
|
||||
},
|
||||
"paraphrase": {
|
||||
"n": 13,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
"phrase": {
|
||||
"n": 7,
|
||||
"hit@5": 0.2857142857142857,
|
||||
"recall@5": 0.09722222222222222,
|
||||
"recall@10": 0.3567176870748299,
|
||||
"mrr@10": 0.3505668934240363
|
||||
},
|
||||
"superseded": {
|
||||
"n": 3,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"mrr@10": 0.0,
|
||||
"outranks": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"rows": [
|
||||
{
|
||||
"id": "q01",
|
||||
"category": "exact_rare",
|
||||
"query": "unjailbreakable",
|
||||
"returned": [
|
||||
"mem-7f61beb4-271c-4feb-9f6e-1c9c837a6226"
|
||||
],
|
||||
"n_returned": 1,
|
||||
"latency_ms": 468.1,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q02",
|
||||
"category": "exact_rare",
|
||||
"query": "engram-migrate",
|
||||
"returned": [
|
||||
"mem-6fdf6545-5e1a-43a9-8bdc-d2cd248146a5"
|
||||
],
|
||||
"n_returned": 1,
|
||||
"latency_ms": 569.9,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q03",
|
||||
"category": "exact_rare",
|
||||
"query": "cartabandonedevent",
|
||||
"returned": [
|
||||
"mem-1ba7c67d-85b9-4c2e-9fe2-39f8b0477091"
|
||||
],
|
||||
"n_returned": 1,
|
||||
"latency_ms": 479.7,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q04",
|
||||
"category": "exact_rare",
|
||||
"query": "pre-apprenticeship",
|
||||
"returned": [
|
||||
"mem-89c02aae-d3ca-43f9-9e5d-eb369896276c"
|
||||
],
|
||||
"n_returned": 1,
|
||||
"latency_ms": 470.4,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q05",
|
||||
"category": "exact_rare",
|
||||
"query": "inferencenodemanager",
|
||||
"returned": [
|
||||
"mem-73969486-143f-4431-b5e6-6845d1cc9848"
|
||||
],
|
||||
"n_returned": 1,
|
||||
"latency_ms": 499.5,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q06",
|
||||
"category": "exact_rare",
|
||||
"query": "clear-eyed",
|
||||
"returned": [
|
||||
"knw-c72597c5-c23d-4c08-8e9e-996dadf26a99"
|
||||
],
|
||||
"n_returned": 1,
|
||||
"latency_ms": 452.8,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q07",
|
||||
"category": "phrase",
|
||||
"query": "patterns not returns",
|
||||
"returned": [
|
||||
"knw-d357b6bb-ad8a-4791-b516-426aea45fa5b",
|
||||
"kn-69fd6e83-7718-4824-8d66-f49d8954e224",
|
||||
"kn-d97920d0-1649-4223-9508-c0bb621e7fc0",
|
||||
"kn-5584ef9c-7f9d-4d7c-a10a-4ee6bc5cf356",
|
||||
"kn-57b4c5e7-40c6-4c90-bf14-71841b0081d4",
|
||||
"kn-eb1c6d99-d603-4f33-be9a-c63a178690c6",
|
||||
"knw-6b48dce2-f21c-452a-9db5-4e6aa61c87ca",
|
||||
"kn-b2a99cd7-b379-4d9b-a996-e347a02c7bad",
|
||||
"bl-76e878aa-e1fe-468c-bf9c-854097cb7e0b",
|
||||
"art-c71aef51-026f-4d63-80e9-2a0ec0dc3865"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1592.0,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q08",
|
||||
"category": "phrase",
|
||||
"query": "thirty moves",
|
||||
"returned": [
|
||||
"knw-7902acca-604e-409b-8faf-ad85424211d0",
|
||||
"knw-2c46cfb4-6d4e-4822-8a1a-7d743c1e4329",
|
||||
"bl-80720fdf-7ce7-4d28-aff8-21028d3a8cfb",
|
||||
"art-2f29ad36-6ee6-4a0e-8d72-0eaf7d12d3a9",
|
||||
"knw-ed33e669-0790-44cb-a036-958d605c6fea",
|
||||
"kn-6061318f-046b-4935-907d-8eafdce14930",
|
||||
"015644f5-8194-4af0-800d-dd4a0cd71396",
|
||||
"art-80ca3d31-84dc-4502-83f4-538372b9764f",
|
||||
"?Z?.\f?0?]P?",
|
||||
"?Q??m?;��`'"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 956.6,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 0.125,
|
||||
"recall@10": 0.1875,
|
||||
"precision@5": 0.4,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q09",
|
||||
"category": "phrase",
|
||||
"query": "Grandma Lucas",
|
||||
"returned": [
|
||||
"kn-a99cefe3-5e83-4050-98d8-6c69f57c7c71",
|
||||
"? ?}&?#??X\b",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c",
|
||||
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
|
||||
"766de879-f9d0-4a07-b6df-b43ee13763d8",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325"
|
||||
],
|
||||
"n_returned": 6,
|
||||
"latency_ms": 970.9,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 0.5555555555555556,
|
||||
"recall@10": 0.5555555555555556,
|
||||
"precision@5": 1.0,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q10",
|
||||
"category": "phrase",
|
||||
"query": "Directed Harmonic",
|
||||
"returned": [
|
||||
"knw-e24d6339-5ff3-4bed-ba53-707ffd0dc70a",
|
||||
"art-e495c8c5-ad95-4b64-8771-f68aa4cfcd0a",
|
||||
"kn-e8423822-eacf-4029-aa7b-10d4d28d621e",
|
||||
"bl-7aebe936-ac55-4f35-8932-adc5224ff854",
|
||||
"kn-9397c74b-35f3-4428-b4b0-5123353bbcd1",
|
||||
"bl-9d53422d-b703-4f1d-860a-8598cb29b792",
|
||||
"mem-60778715-758c-4677-933d-fc39b8f94152",
|
||||
"? ?}&?#??X\b",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"mem-7eeacad7-d7c2-4c2b-8348-19a59aa6dbaf"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 920.3,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.1111111111111111,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.1
|
||||
},
|
||||
{
|
||||
"id": "q11",
|
||||
"category": "phrase",
|
||||
"query": "Sarah Bishop",
|
||||
"returned": [
|
||||
"art-4a99aa1a-489b-4b43-958b-25217adb1aad",
|
||||
"art-8dbceb06-431a-416d-a723-e8c75d595154",
|
||||
"mem-a3124d5b-2f50-477f-8bb5-06879f5a496c",
|
||||
"knw-528dbc37-eabc-4b75-a7a5-65bf38d6018a",
|
||||
"art-94fae615-7cd5-4695-b968-977101b06a51",
|
||||
"art-2fabd873-d787-49cb-ad30-d4ed9fcff8ef",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 925.0,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.5,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.1111111111111111
|
||||
},
|
||||
{
|
||||
"id": "q12",
|
||||
"category": "phrase",
|
||||
"query": "Directed Autonomous Runtime Modification",
|
||||
"returned": [
|
||||
"kn-f8974b26-78a6-4aad-b893-19a73b20013d",
|
||||
"mem-46780047-63a0-4a86-a16b-638b72a7fb8d",
|
||||
"kn-8e1bfb48-33a9-45ad-8da7-e0bdaa5d34e7",
|
||||
"mem-cdff0c49-3ac7-4de8-89ec-92d254bd0023",
|
||||
"bl-a7a1428f-db9c-417b-8e2c-713b1f84dc1f",
|
||||
"mem-f823e835-313f-4282-b4b3-ce527ffc2f7a",
|
||||
"? ?}&?#??X\b",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"?Z?.\f?0?]P?",
|
||||
"bl-145a0985-2382-400f-a7c5-c335c5e30a72"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 2455.6,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.14285714285714285,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.14285714285714285
|
||||
},
|
||||
{
|
||||
"id": "q13",
|
||||
"category": "phrase",
|
||||
"query": "zero-knowledge encrypted backup",
|
||||
"returned": [
|
||||
"art-92e1837c-5919-42d0-bbb0-4d924d7b2864",
|
||||
"bl-e20944e5-eb16-4ab3-a84d-111e0fc817fa",
|
||||
"bl-e20944e5-f4a6-44a0-91b1-73d04ebed120",
|
||||
"mem-47f72b5b-6e8b-4293-94f1-350197b4809a",
|
||||
"mem-e612f0aa-c2f2-4ee3-bbc7-af2dc826233b",
|
||||
"mem-a5f04e52-91f8-41d2-af27-8bf803621758",
|
||||
"7774a16c-1027-4e3b-a21e-67f1f95a4acd",
|
||||
"? ?}&?#??X\b",
|
||||
"7?e?7???\f3?",
|
||||
"deda48cd-5e1a-46cb-bd43-8016afdb3a8a"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 2037.1,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.1
|
||||
},
|
||||
{
|
||||
"id": "q14",
|
||||
"category": "paraphrase",
|
||||
"query": "the elderly relative who passed while he stayed away",
|
||||
"returned": [
|
||||
"kn-82be4e41-96c5-4da3-85c0-cee10763d975",
|
||||
"mem-ea487cb4-ed67-44ce-8402-b56bb28468d4",
|
||||
"mem-23d22bc1-a097-446b-8f11-8aff099e0b76",
|
||||
"bl-874d1c2b-c55b-4afb-9601-922a9297e859",
|
||||
"bl-2dd8aaa1-b0de-4eac-b3c5-78951d240b60",
|
||||
"bl-2694b588-a6e3-43de-861c-fa7b0ec7e7fd",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c",
|
||||
"? ?}&?#??X\b",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
|
||||
"art-4a99aa1a-489b-4b43-958b-25217adb1aad"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 4720.4,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q15",
|
||||
"category": "paraphrase",
|
||||
"query": "a soldier sidelined by illness who refused to quit",
|
||||
"returned": [
|
||||
"mem-0328c3cb-4550-4ce4-9284-152e832f08f6",
|
||||
"bl-07375bf9-a169-42cd-adb3-7d32b25982f0",
|
||||
"bl-fd047ce9-ae21-4b3e-b3ab-ece0c9592f7f",
|
||||
"kn-57b4c5e7-40c6-4c90-bf14-71841b0081d4",
|
||||
"bl-6172d035-dd94-4776-afdd-d8915f6fc375",
|
||||
"bl-5bb8dedf-8498-4a9b-acdc-31cc9c738f2a",
|
||||
"art-2f29ad36-6ee6-4a0e-8d72-0eaf7d12d3a9",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c",
|
||||
"art-80ca3d31-84dc-4502-83f4-538372b9764f",
|
||||
"015644f5-8194-4af0-800d-dd4a0cd71396"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 5078.8,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q16",
|
||||
"category": "paraphrase",
|
||||
"query": "choosing an uncomfortable fact over a pleasant fiction",
|
||||
"returned": [
|
||||
"bl-e5635b1a-c5d0-4caa-bcc8-6a726ea43685",
|
||||
"bl-fc893be3-e6b4-4ef6-93b0-d54ca5f89083",
|
||||
"tag-project-structure",
|
||||
"tag-anthropic-contrast",
|
||||
"tag-voice-training",
|
||||
"tag-ebd",
|
||||
"art-80ca3d31-84dc-4502-83f4-538372b9764f",
|
||||
"015644f5-8194-4af0-800d-dd4a0cd71396",
|
||||
"bl-9d53422d-b703-4f1d-860a-8598cb29b792",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 4118.0,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q17",
|
||||
"category": "paraphrase",
|
||||
"query": "a tight payload beats a bloated one",
|
||||
"returned": [
|
||||
"bl-d24fcce8-2b55-426f-867a-db3958a622d3",
|
||||
"tag-phase-3",
|
||||
"tag-identity-studio",
|
||||
"tag-kids",
|
||||
"tag-coexistence",
|
||||
"tag-cultivated-general-intelligence",
|
||||
"015644f5-8194-4af0-800d-dd4a0cd71396",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-9397c74b-35f3-4428-b4b0-5123353bbcd1",
|
||||
"mem-cdff0c49-3ac7-4de8-89ec-92d254bd0023"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 3241.8,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q18",
|
||||
"category": "paraphrase",
|
||||
"query": "if you are able and nobody is coming the job is yours",
|
||||
"returned": [
|
||||
"knw-7902acca-604e-409b-8faf-ad85424211d0",
|
||||
"bl-bd9fb314-e9d4-4b03-aef4-534dd57a2992",
|
||||
"bl-b019ce7a-1b21-436e-812d-032f50c6c45f",
|
||||
"bl-e98cdd4c-01b5-459e-9036-3578cd5d975a",
|
||||
"bl-9ce4128a-9436-4b06-82bc-8a6faafa81e0",
|
||||
"tag-stable-diffusion",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c",
|
||||
"art-80ca3d31-84dc-4502-83f4-538372b9764f",
|
||||
"015644f5-8194-4af0-800d-dd4a0cd71396",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 4090.9,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q19",
|
||||
"category": "paraphrase",
|
||||
"query": "learning is the wealth creditors cannot seize",
|
||||
"returned": [
|
||||
"mem-e321e54e-8bb3-4596-b13d-bb093d6b149d",
|
||||
"mem-e32ba5a7-c147-4dc0-9479-b720d768eda6",
|
||||
"mem-c7a77457-478d-4eb0-a116-67205a0066a4",
|
||||
"bl-1b20e9bc-eb37-4907-8d63-e311fd61eab8",
|
||||
"bl-aa762207-920d-45ab-b2a3-2f8154d7ef9b",
|
||||
"tag-misalignment",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c",
|
||||
"015644f5-8194-4af0-800d-dd4a0cd71396",
|
||||
"? ?}&?#??X\b",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 3671.5,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q20",
|
||||
"category": "paraphrase",
|
||||
"query": "reliability proven by track record not assertion",
|
||||
"returned": [
|
||||
"kn-48a01973-a025-471d-950f-b93e6a426d82",
|
||||
"bl-7f33f1bc-99fa-4906-889f-a42375beea20",
|
||||
"mem-6f0b2b45-90c1-4356-ac01-3daac05b09c8",
|
||||
"mem-ce5a2ffc-ad39-4728-9ac6-76fef507d5da",
|
||||
"project-Stripe_Elements__not_hosted_checkout__Custom_URL__DAG_bundle_pricing__Stripe_Connect_80_20_",
|
||||
"tag-provenance",
|
||||
"? ?}&?#??X\b",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"art-2f29ad36-6ee6-4a0e-8d72-0eaf7d12d3a9",
|
||||
"art-e495c8c5-ad95-4b64-8771-f68aa4cfcd0a"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 4674.3,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q21",
|
||||
"category": "paraphrase",
|
||||
"query": "boundaries that enable instead of confine",
|
||||
"returned": [
|
||||
"kn-79056192-7de8-486c-9565-f128439a6fcb",
|
||||
"bl-f6236350-f7b8-4f4f-a702-9eef2eb76e4b",
|
||||
"mem-ef0091d8-1b65-431e-afa8-c6c4ee5779c9",
|
||||
"mem-37b57f52-a29a-42cf-a07a-3c5f8a3598dd",
|
||||
"mem-1f32f73a-952c-41bc-96dc-8b8b70d8a7c1",
|
||||
"tag-__cultivation-metric____internal-state____dharma____evidence____novel-idea____gap-compression____values____microsoft__",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-9397c74b-35f3-4428-b4b0-5123353bbcd1",
|
||||
"art-80ca3d31-84dc-4502-83f4-538372b9764f",
|
||||
"015644f5-8194-4af0-800d-dd4a0cd71396"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 3974.1,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q22",
|
||||
"category": "paraphrase",
|
||||
"query": "what shifts tells you where to cut a system apart",
|
||||
"returned": [
|
||||
"knw-723551f5-1950-42a3-8b89-b6a06913cef0",
|
||||
"bl-57c5cf6b-81a5-4558-9902-5c02981fe273",
|
||||
"tag-guilds",
|
||||
"tag-finance",
|
||||
"tag-temporal",
|
||||
"tag-barkhausen",
|
||||
"tag-ilogger",
|
||||
"015644f5-8194-4af0-800d-dd4a0cd71396",
|
||||
"kn-9397c74b-35f3-4428-b4b0-5123353bbcd1",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 4851.9,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q23",
|
||||
"category": "paraphrase",
|
||||
"query": "a mind that compounds instead of resetting each day",
|
||||
"returned": [
|
||||
"project-Goal_setting__alignment__scoring__cadence__Attaches_to_any_imprint_",
|
||||
"tag-turing-test",
|
||||
"tag-sealed",
|
||||
"tag-design-first",
|
||||
"tag-part-5",
|
||||
"tag-model",
|
||||
"art-80ca3d31-84dc-4502-83f4-538372b9764f",
|
||||
"015644f5-8194-4af0-800d-dd4a0cd71396",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
|
||||
"? ?}&?#??X\b"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 4505.1,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q24",
|
||||
"category": "paraphrase",
|
||||
"query": "loved for the unedited self and not the polished exterior",
|
||||
"returned": [
|
||||
"mem-9590ba23-bddb-43e8-a571-68a263c4c364",
|
||||
"bl-a9e57bb2-00a1-4867-ab59-5d9271134b50",
|
||||
"tag-performed-values",
|
||||
"bl-c7793c4a-7630-47fc-a462-d23059087e80",
|
||||
"tag-gateway_platform_neuron-technologies_go_proxy_llm",
|
||||
"tag-fornax",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
|
||||
"art-80ca3d31-84dc-4502-83f4-538372b9764f",
|
||||
"015644f5-8194-4af0-800d-dd4a0cd71396"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 4494.1,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q25",
|
||||
"category": "paraphrase",
|
||||
"query": "cheerfulness you arrive at instead of assuming",
|
||||
"returned": [
|
||||
"bl-7a13527b-3e0c-418a-9f37-88fd2152e5ce",
|
||||
"bl-3f57bc69-7285-4f4a-a861-2de52efca058",
|
||||
"bl-5e390b10-8753-4f25-a1a5-b5dbbb002cbf",
|
||||
"tag-ats",
|
||||
"tag-data-model",
|
||||
"tag-aggregation",
|
||||
"015644f5-8194-4af0-800d-dd4a0cd71396",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c",
|
||||
"art-80ca3d31-84dc-4502-83f4-538372b9764f",
|
||||
"? ?}&?#??X\b"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 3619.4,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q26",
|
||||
"category": "paraphrase",
|
||||
"query": "a childhood offering no solid foundation to inherit",
|
||||
"returned": [
|
||||
"tag-memory-model",
|
||||
"tag-storage",
|
||||
"tag-ga4",
|
||||
"tag-potions",
|
||||
"tag-resonance",
|
||||
"tag-neuron",
|
||||
"? ?}&?#??X\b",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 4107.0,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q27",
|
||||
"category": "associative",
|
||||
"query": "Grandma Lucas stroke February 2006 goodbye window",
|
||||
"returned": [
|
||||
"mem-927f41ab-8ede-4f58-acb3-995db16ac775",
|
||||
"mem-dbe80bc2-c602-46b0-b4ea-dd222e52bcde",
|
||||
"mem-82158b02-a180-435d-84f0-0b7ce37511b4",
|
||||
"bl-33ecccc2-e37f-43db-91b3-c2a86f08aaac",
|
||||
"bl-4476e856-c567-4b49-8ff7-d7dca3e5715e",
|
||||
"tag-upload-window",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
|
||||
"kn-a99cefe3-5e83-4050-98d8-6c69f57c7c71",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 4231.0,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q28",
|
||||
"category": "associative",
|
||||
"query": "Marines hernia sepsis medical ward",
|
||||
"returned": [
|
||||
"knw-08559f5c-2306-4220-a146-398c74f1643c",
|
||||
"knw-920c891f-bb8c-48c4-9afc-018ef12dcdc4",
|
||||
"mem-434be7c8-88cb-4039-b79a-1da4ac4de783",
|
||||
"mem-481c769c-68cc-45c7-bc37-c0d9778fa648",
|
||||
"bl-5b17bd3b-0c41-46cb-a710-6fa4429692ff",
|
||||
"bl-9d8f3c5b-4bac-41ce-8ac4-44733f99d6c8",
|
||||
"bl-33ecccc2-e37f-43db-91b3-c2a86f08aaac",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
|
||||
"kn-58874a74-b96f-4883-9e08-45707f4bd3ee",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 3208.8,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q29",
|
||||
"category": "associative",
|
||||
"query": "Sarah Bishop Dyer trailer performance",
|
||||
"returned": [
|
||||
"kn-58874a74-b96f-4883-9e08-45707f4bd3ee",
|
||||
"project-Imprint__leadership_development__feedback_frameworks__performance__presence_",
|
||||
"mem-5e7f6ddd-c818-4ad3-b564-54ae278e9976",
|
||||
"bl-7fa1b1a8-b80a-4f28-b162-bfe73765b4f8",
|
||||
"mem-89c02aae-d3ca-43f9-9e5d-eb369896276c",
|
||||
"tag-sarah",
|
||||
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
|
||||
"? ?}&?#??X\b",
|
||||
"art-4a99aa1a-489b-4b43-958b-25217adb1aad",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 2359.6,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q30",
|
||||
"category": "associative",
|
||||
"query": "Swarm Architecture containment lateral worker",
|
||||
"returned": [
|
||||
"mem-265a7107-73b3-4410-9aff-43787d5f473b",
|
||||
"mem-9d1bf963-1b40-4588-bdb3-0432646cc623",
|
||||
"bl-0de4e61b-6562-49e5-b7df-ebb809a01723",
|
||||
"mem-3987d374-3c48-4e8e-b06d-0c363f55ed9c",
|
||||
"bl-e0a0df72-de6e-46ab-800b-e1e3e8dfc387",
|
||||
"tag-__patents____swarm____claim-language____prior-art____filing__",
|
||||
"? ?}&?#??X\b",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"7?e?7???\f3?",
|
||||
"?of?7???"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 2342.5,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q31",
|
||||
"category": "associative",
|
||||
"query": "hope won inside the narrative preface",
|
||||
"returned": [
|
||||
"kn-dca14c4c-4859-47b0-996e-33964ba61a87",
|
||||
"bl-e148d23c-24e8-4122-9915-d1c11f22052f",
|
||||
"bl-31abf75b-998f-4a4f-a6dd-8204119e0451",
|
||||
"bl-dc8c7e02-eb37-48ae-a6f8-9b512803ae16",
|
||||
"mem-8d1bafe6-209c-456c-9a25-9a927bc5a16d",
|
||||
"bl-14883d81-f7cb-46dd-82c2-a6e6980264e5",
|
||||
"? ?}&?#??X\b",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
|
||||
"?Q??m?;��`'",
|
||||
"R^??m?;��?'"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 3536.5,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q32",
|
||||
"category": "associative",
|
||||
"query": "man of the house six years old expectation",
|
||||
"returned": [
|
||||
"kn-eb1b9e18-3dc6-4b9b-9cc6-86e0ae6b6be8",
|
||||
"bl-ffa22d7e-42a9-4bd2-a428-1d2df243ac93",
|
||||
"bl-452a4710-3d2b-4e0f-9413-49a66423bc9a",
|
||||
"bl-4a6746e8-191f-48fc-8bfb-c4dc73b80bcd",
|
||||
"tag-command-pattern",
|
||||
"tag-withholding",
|
||||
"tag-offline",
|
||||
"art-80ca3d31-84dc-4502-83f4-538372b9764f",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c",
|
||||
"? ?}&?#??X\b"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 4151.6,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q33",
|
||||
"category": "nonsense",
|
||||
"query": "zqxjvw plimforth grebulon",
|
||||
"returned": [],
|
||||
"n_returned": 0,
|
||||
"latency_ms": 1342.7,
|
||||
"error": null,
|
||||
"clean": true,
|
||||
"false_positives": 0
|
||||
},
|
||||
{
|
||||
"id": "q34",
|
||||
"category": "nonsense",
|
||||
"query": "flarnbistle quommetry",
|
||||
"returned": [],
|
||||
"n_returned": 0,
|
||||
"latency_ms": 874.8,
|
||||
"error": null,
|
||||
"clean": true,
|
||||
"false_positives": 0
|
||||
},
|
||||
{
|
||||
"id": "q35",
|
||||
"category": "nonsense",
|
||||
"query": "xxqzzt vurblenacht throom",
|
||||
"returned": [
|
||||
"kn-333542cb-6dab-4662-9725-bf7440d28bf7",
|
||||
"? ?}&?#??X\b",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325",
|
||||
"kn-66a21179-2adc-4b19-a109-880cf4674d7d",
|
||||
"bl-4476e856-c567-4b49-8ff7-d7dca3e5715e",
|
||||
"art-4a99aa1a-489b-4b43-958b-25217adb1aad",
|
||||
"knw-920c891f-bb8c-48c4-9afc-018ef12dcdc4"
|
||||
],
|
||||
"n_returned": 8,
|
||||
"latency_ms": 1374.6,
|
||||
"error": null,
|
||||
"clean": false,
|
||||
"false_positives": 8
|
||||
},
|
||||
{
|
||||
"id": "q36",
|
||||
"category": "superseded",
|
||||
"query": "is the self-improvement architecture called DARMA or DHARMA",
|
||||
"returned": [
|
||||
"ctx-e5427d7d",
|
||||
"project-worldweaver",
|
||||
"tag-__kotlin____internal-state____pre-reasoning____post-reasoning____compression-ratio____dharma____cultivation__",
|
||||
"tag-import",
|
||||
"tag-enterprise",
|
||||
"tag-__cgi____dharma____cultivation____five-primitives____seed-artifact____agi____intelligence____whitepaper____patent__",
|
||||
"art-80ca3d31-84dc-4502-83f4-538372b9764f",
|
||||
"? ?}&?#??X\b",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325",
|
||||
"015644f5-8194-4af0-800d-dd4a0cd71396"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 3762.6,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0,
|
||||
"outranks": false,
|
||||
"rank_correct": null,
|
||||
"rank_stale": null
|
||||
},
|
||||
{
|
||||
"id": "q37",
|
||||
"category": "superseded",
|
||||
"query": "how many provisional patents does Will actually have",
|
||||
"returned": [
|
||||
"mem-bfe0fafd-2750-4fdc-b773-04e878b3b23f",
|
||||
"art-7bdaff30-5af9-4f0a-93b1-751686f9de3d",
|
||||
"mem-cf07910d-4676-4384-ab97-9cad946cd0b9",
|
||||
"project-Convert_UTC_timestamps_to_Central_time_when_displaying_to_Will__Never_surface_raw_UTC_",
|
||||
"mem-32203649-3213-4d6d-86fd-3d657ac70d77",
|
||||
"mem-22f5f665-3ad2-4063-88b0-915849a795f5",
|
||||
"? ?}&?#??X\b",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c",
|
||||
"art-80ca3d31-84dc-4502-83f4-538372b9764f",
|
||||
"015644f5-8194-4af0-800d-dd4a0cd71396"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 4859.0,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0,
|
||||
"outranks": false,
|
||||
"rank_correct": null,
|
||||
"rank_stale": null
|
||||
},
|
||||
{
|
||||
"id": "q38",
|
||||
"category": "superseded",
|
||||
"query": "is MCP still the live integration layer",
|
||||
"returned": [
|
||||
"project-Imprint__discovery__objection_handling__deal_strategy__pipeline__closing_",
|
||||
"bl-8116da7a-b039-4e08-b8d0-c1c7861f9766",
|
||||
"bl-8ef1ba6b-3fa0-4dbd-98c5-31665e5694a1",
|
||||
"tag-dark-theme",
|
||||
"tag-divisors",
|
||||
"tag-distressed-property",
|
||||
"? ?}&?#??X\b",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325",
|
||||
"kn-9397c74b-35f3-4428-b4b0-5123353bbcd1",
|
||||
"???Ͼd??W\b?"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 2873.3,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0,
|
||||
"outranks": false,
|
||||
"rank_correct": null,
|
||||
"rank_stale": null
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,945 @@
|
||||
{
|
||||
"label": "main-r2",
|
||||
"soul_binary": "/private/tmp/claude-501/-Users-timlingo/82369039-a20e-4b5a-8a5e-28234a57b996/scratchpad/soul-main",
|
||||
"soul_md5": "caf822425540114984bfcd713ad37162",
|
||||
"corpus": "/Users/timlingo/neuron-memory-backups/snapshot-pre-repair-20260806.json",
|
||||
"corpus_nodes": 78768,
|
||||
"corpus_edges": 14214,
|
||||
"gold_set": "/Users/timlingo/Development/neuron-technologies/_wt-eval/tools/retrieval-eval/gold_set.json",
|
||||
"limit": 10,
|
||||
"port": 7895,
|
||||
"wall_clock_s": 45.6,
|
||||
"child_pid": 78695,
|
||||
"child_confirmed_dead": true,
|
||||
"aggregate": {
|
||||
"n_queries": 38,
|
||||
"n_scored": 35,
|
||||
"hit@5": 0.34285714285714286,
|
||||
"recall@5": 0.26947278911564626,
|
||||
"recall@10": 0.3333333333333333,
|
||||
"precision@5": 0.12000000000000001,
|
||||
"mrr@10": 0.2943197278911564,
|
||||
"nonsense_clean": "2/3",
|
||||
"superseded_outranks": "1/3",
|
||||
"latency_ms_p50": 1151.1,
|
||||
"latency_ms_p95": 1580.7,
|
||||
"latency_ms_max": 1663.2,
|
||||
"errors": 0,
|
||||
"by_category": {
|
||||
"associative": {
|
||||
"n": 6,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
"exact_rare": {
|
||||
"n": 6,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
"nonsense": {
|
||||
"n": 3,
|
||||
"clean": 2,
|
||||
"avg_false_positives": 3.3333333333333335
|
||||
},
|
||||
"paraphrase": {
|
||||
"n": 13,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
"phrase": {
|
||||
"n": 7,
|
||||
"hit@5": 0.8571428571428571,
|
||||
"recall@5": 0.4902210884353741,
|
||||
"recall@10": 0.6666666666666666,
|
||||
"mrr@10": 0.5965986394557822
|
||||
},
|
||||
"superseded": {
|
||||
"n": 3,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.3333333333333333,
|
||||
"mrr@10": 0.041666666666666664,
|
||||
"outranks": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"rows": [
|
||||
{
|
||||
"id": "q01",
|
||||
"category": "exact_rare",
|
||||
"query": "unjailbreakable",
|
||||
"returned": [
|
||||
"mem-7f61beb4-271c-4feb-9f6e-1c9c837a6226"
|
||||
],
|
||||
"n_returned": 1,
|
||||
"latency_ms": 231.3,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q02",
|
||||
"category": "exact_rare",
|
||||
"query": "engram-migrate",
|
||||
"returned": [
|
||||
"mem-6fdf6545-5e1a-43a9-8bdc-d2cd248146a5"
|
||||
],
|
||||
"n_returned": 1,
|
||||
"latency_ms": 266.6,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q03",
|
||||
"category": "exact_rare",
|
||||
"query": "cartabandonedevent",
|
||||
"returned": [
|
||||
"mem-1ba7c67d-85b9-4c2e-9fe2-39f8b0477091"
|
||||
],
|
||||
"n_returned": 1,
|
||||
"latency_ms": 229.2,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q04",
|
||||
"category": "exact_rare",
|
||||
"query": "pre-apprenticeship",
|
||||
"returned": [
|
||||
"mem-89c02aae-d3ca-43f9-9e5d-eb369896276c"
|
||||
],
|
||||
"n_returned": 1,
|
||||
"latency_ms": 235.8,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q05",
|
||||
"category": "exact_rare",
|
||||
"query": "inferencenodemanager",
|
||||
"returned": [
|
||||
"mem-73969486-143f-4431-b5e6-6845d1cc9848"
|
||||
],
|
||||
"n_returned": 1,
|
||||
"latency_ms": 254.1,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q06",
|
||||
"category": "exact_rare",
|
||||
"query": "clear-eyed",
|
||||
"returned": [
|
||||
"knw-c72597c5-c23d-4c08-8e9e-996dadf26a99"
|
||||
],
|
||||
"n_returned": 1,
|
||||
"latency_ms": 228.8,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q07",
|
||||
"category": "phrase",
|
||||
"query": "patterns not returns",
|
||||
"returned": [
|
||||
"kn-57b4c5e7-40c6-4c90-bf14-71841b0081d4",
|
||||
"?ǚ?7??????",
|
||||
"mem-a4a9dfc3-e40b-49b3-b1e1-060e8be2f482",
|
||||
"kn-5584ef9c-7f9d-4d7c-a10a-4ee6bc5cf356",
|
||||
"015644f5-8194-4af0-800d-dd4a0cd71396",
|
||||
"????7???Ջ3",
|
||||
"kn-d97920d0-1649-4223-9508-c0bb621e7fc0",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"art-d24fd6dd-2cda-4eed-92f3-67b535a0d71b",
|
||||
"7?e?7???\f3?"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 543.3,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 0.3333333333333333
|
||||
},
|
||||
{
|
||||
"id": "q08",
|
||||
"category": "phrase",
|
||||
"query": "thirty moves",
|
||||
"returned": [
|
||||
"knw-4aebd815-4eaf-49d7-954b-03595f3d48be",
|
||||
"knw-7902acca-604e-409b-8faf-ad85424211d0",
|
||||
"knw-2c46cfb4-6d4e-4822-8a1a-7d743c1e4329",
|
||||
"art-4a99aa1a-489b-4b43-958b-25217adb1aad",
|
||||
"knw-f671966c-3387-4848-abca-b5deec122e00",
|
||||
"knw-e94982a2-358d-4f2f-af31-8ee0fcec07c6",
|
||||
"Z[?<S???H??",
|
||||
"rQ??m?;?x?'",
|
||||
"kn-f230b362-b201-4402-9833-4160c89ab3d4",
|
||||
"kn-6061318f-046b-4935-907d-8eafdce14930"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 466.4,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 0.3125,
|
||||
"recall@10": 0.5,
|
||||
"precision@5": 1.0,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q09",
|
||||
"category": "phrase",
|
||||
"query": "Grandma Lucas",
|
||||
"returned": [
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c",
|
||||
"kn-a99cefe3-5e83-4050-98d8-6c69f57c7c71",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"766de879-f9d0-4a07-b6df-b43ee13763d8",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 474.9,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 0.3333333333333333,
|
||||
"recall@10": 0.5555555555555556,
|
||||
"precision@5": 0.6,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q10",
|
||||
"category": "phrase",
|
||||
"query": "Directed Harmonic",
|
||||
"returned": [
|
||||
"kn-5584ef9c-7f9d-4d7c-a10a-4ee6bc5cf356",
|
||||
"ԍ????X????",
|
||||
"bl-dcee1887-34c4-4ffa-9119-1e291685ba08",
|
||||
"?ǚ?7??????",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"knw-e24d6339-5ff3-4bed-ba53-707ffd0dc70a",
|
||||
"mem-7eeacad7-d7c2-4c2b-8348-19a59aa6dbaf",
|
||||
"????7???Ջ3",
|
||||
"??????X??2c",
|
||||
"g?e?7???'c?"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 460.6,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.1111111111111111,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.14285714285714285
|
||||
},
|
||||
{
|
||||
"id": "q11",
|
||||
"category": "phrase",
|
||||
"query": "Sarah Bishop",
|
||||
"returned": [
|
||||
"art-4a99aa1a-489b-4b43-958b-25217adb1aad",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"766de879-f9d0-4a07-b6df-b43ee13763d8",
|
||||
"mem-a9a9ce95-0d64-46eb-9db8-ff81d78ade35",
|
||||
"mem-b8ecd23e-77ce-42f7-984c-f51453fec16d"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 477.1,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 0.5,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 0.2
|
||||
},
|
||||
{
|
||||
"id": "q12",
|
||||
"category": "phrase",
|
||||
"query": "Directed Autonomous Runtime Modification",
|
||||
"returned": [
|
||||
"bl-5b17bd3b-0c41-46cb-a710-6fa4429692ff",
|
||||
"bl-145a0985-2382-400f-a7c5-c335c5e30a72",
|
||||
"mem-82b93b21-a865-410f-9ec1-fc54121d9bb5",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"mem-e6327f52-2bda-4ce7-9471-2fffd1e172de",
|
||||
"7?e?7???\f3?",
|
||||
"?of?7???",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b"
|
||||
],
|
||||
"n_returned": 9,
|
||||
"latency_ms": 824.1,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 0.2857142857142857,
|
||||
"recall@10": 0.5,
|
||||
"precision@5": 0.8,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q13",
|
||||
"category": "phrase",
|
||||
"query": "zero-knowledge encrypted backup",
|
||||
"returned": [
|
||||
"7774a16c-1027-4e3b-a21e-67f1f95a4acd",
|
||||
"deda48cd-5e1a-46cb-bd43-8016afdb3a8a",
|
||||
"mem-dba009a2-d2ea-4f5a-b9e8-0f04bc9ab32f",
|
||||
"mem-a3c97012-5fa3-4915-a839-2c75c72005e0",
|
||||
"mem-7cd90611-88a3-423d-a38a-0db2812952fa",
|
||||
"bl-07375bf9-a169-42cd-adb3-7d32b25982f0",
|
||||
"bl-ec84b63d-b278-4944-8d7f-4aa7a51c0315",
|
||||
"7?e?7???\f3?",
|
||||
"?of?7???",
|
||||
"? ?}&?#??X\b"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 681.5,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 0.5
|
||||
},
|
||||
{
|
||||
"id": "q14",
|
||||
"category": "paraphrase",
|
||||
"query": "the elderly relative who passed while he stayed away",
|
||||
"returned": [
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"art-4a99aa1a-489b-4b43-958b-25217adb1aad",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"????7???Ջ3",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1577.6,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q15",
|
||||
"category": "paraphrase",
|
||||
"query": "a soldier sidelined by illness who refused to quit",
|
||||
"returned": [
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325",
|
||||
"art-2fabd873-d787-49cb-ad30-d4ed9fcff8ef",
|
||||
"art-2f29ad36-6ee6-4a0e-8d72-0eaf7d12d3a9",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-a31e1001-342e-4deb-a2e6-6d02d1f22dee",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"knw-9e74ee95-ba7d-49b1-9262-977eae9729d1",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1663.2,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q16",
|
||||
"category": "paraphrase",
|
||||
"query": "choosing an uncomfortable fact over a pleasant fiction",
|
||||
"returned": [
|
||||
"7?e?7???\f3?",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-f8974b26-78a6-4aad-b893-19a73b20013d",
|
||||
"?of?7???",
|
||||
"????7???Ջ3",
|
||||
"kn-d97920d0-1649-4223-9508-c0bb621e7fc0",
|
||||
"kn-57b4c5e7-40c6-4c90-bf14-71841b0081d4",
|
||||
"kn-9397c74b-35f3-4428-b4b0-5123353bbcd1",
|
||||
"kn-81c24d13-a73b-4767-819c-dafaacc1498e",
|
||||
"? ?}&?#??X\b"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1331.8,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q17",
|
||||
"category": "paraphrase",
|
||||
"query": "a tight payload beats a bloated one",
|
||||
"returned": [
|
||||
"kn-d7c1e0fb-fa59-46d3-b4c9-a0d1d437a491",
|
||||
"7?e?7???\f3?",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-e8423822-eacf-4029-aa7b-10d4d28d621e",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"??o?'?B???k",
|
||||
"kn-9397c74b-35f3-4428-b4b0-5123353bbcd1",
|
||||
"? ?}&?#??X\b",
|
||||
"?of?7???"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1036.0,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q18",
|
||||
"category": "paraphrase",
|
||||
"query": "if you are able and nobody is coming the job is yours",
|
||||
"returned": [
|
||||
"7?e?7???\f3?",
|
||||
"?of?7???",
|
||||
"imp-dce1da0f-8776-4a9e-972b-33411a7ca138",
|
||||
"kn-5b606390-a52d-4ca2-8e0e-eba141d13440",
|
||||
"kn-83bb86c6-521d-416c-a86e-6e29c2d8f102",
|
||||
"kn-f8974b26-78a6-4aad-b893-19a73b20013d",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b"
|
||||
],
|
||||
"n_returned": 9,
|
||||
"latency_ms": 1363.5,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q19",
|
||||
"category": "paraphrase",
|
||||
"query": "learning is the wealth creditors cannot seize",
|
||||
"returned": [
|
||||
"kn-5584ef9c-7f9d-4d7c-a10a-4ee6bc5cf356",
|
||||
"knw-7902acca-604e-409b-8faf-ad85424211d0",
|
||||
"knw-e24d6339-5ff3-4bed-ba53-707ffd0dc70a",
|
||||
"kn-57b4c5e7-40c6-4c90-bf14-71841b0081d4",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"7?e?7???\f3?",
|
||||
"??o?'?B???k",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-0625e393-067c-4bba-8389-7e1b79265142",
|
||||
"ע?RGk?\tH(?"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1230.4,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q20",
|
||||
"category": "paraphrase",
|
||||
"query": "reliability proven by track record not assertion",
|
||||
"returned": [
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"7?e?7???\f3?",
|
||||
"?of?7???",
|
||||
"art-2fabd873-d787-49cb-ad30-d4ed9fcff8ef",
|
||||
"kn-5584ef9c-7f9d-4d7c-a10a-4ee6bc5cf356"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1548.1,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q21",
|
||||
"category": "paraphrase",
|
||||
"query": "boundaries that enable instead of confine",
|
||||
"returned": [
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"??????X??2c",
|
||||
"ԍ????X????",
|
||||
"dR????X?-?S",
|
||||
"kn-5584ef9c-7f9d-4d7c-a10a-4ee6bc5cf356",
|
||||
"dz????Xƹ?i",
|
||||
"kn-d7c1e0fb-fa59-46d3-b4c9-a0d1d437a491"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1315.4,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q22",
|
||||
"category": "paraphrase",
|
||||
"query": "what shifts tells you where to cut a system apart",
|
||||
"returned": [
|
||||
"7?e?7???\f3?",
|
||||
"kn-9397c74b-35f3-4428-b4b0-5123353bbcd1",
|
||||
"?of?7???",
|
||||
"kn-f8974b26-78a6-4aad-b893-19a73b20013d",
|
||||
"knw-9e74ee95-ba7d-49b1-9262-977eae9729d1",
|
||||
"dR????X?-?S",
|
||||
"dz????Xƹ?i",
|
||||
"ԍ????X????",
|
||||
"??????X??2c",
|
||||
"kn-d7c1e0fb-fa59-46d3-b4c9-a0d1d437a491"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1580.7,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q23",
|
||||
"category": "paraphrase",
|
||||
"query": "a mind that compounds instead of resetting each day",
|
||||
"returned": [
|
||||
"?ǚ?7??????",
|
||||
"kn-5584ef9c-7f9d-4d7c-a10a-4ee6bc5cf356",
|
||||
"????7???Ջ3",
|
||||
"7?e?7???\f3?",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-9397c74b-35f3-4428-b4b0-5123353bbcd1",
|
||||
"%???2??jH??",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"?of?7???"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1474.1,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q24",
|
||||
"category": "paraphrase",
|
||||
"query": "loved for the unedited self and not the polished exterior",
|
||||
"returned": [
|
||||
"mem-bbb126a1-b297-42bb-86be-796871829c94",
|
||||
"mem-45022957-2d78-48aa-a714-16d6eca52e0f",
|
||||
"art-4a99aa1a-489b-4b43-958b-25217adb1aad",
|
||||
"knw-35940684-abc4-42f0-b942-818f66b1f69a",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
|
||||
"7?e?7???\f3?",
|
||||
"? ?}&?#??X\b",
|
||||
"'?T?a\"B~-?8"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1490.4,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q25",
|
||||
"category": "paraphrase",
|
||||
"query": "cheerfulness you arrive at instead of assuming",
|
||||
"returned": [
|
||||
"015644f5-8194-4af0-800d-dd4a0cd71396",
|
||||
"?ǚ?7??????",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325",
|
||||
"7?e?7???\f3?",
|
||||
"kn-e8423822-eacf-4029-aa7b-10d4d28d621e",
|
||||
"??S?7???",
|
||||
"? ?}&?#??X\b",
|
||||
"??f?7???",
|
||||
"??S?7???",
|
||||
"knw-5578cb21-e899-4822-b7f4-0d96fa094e3d"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1192.2,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q26",
|
||||
"category": "paraphrase",
|
||||
"query": "a childhood offering no solid foundation to inherit",
|
||||
"returned": [
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"7?e?7???\f3?",
|
||||
"kn-e8423822-eacf-4029-aa7b-10d4d28d621e",
|
||||
"? ?}&?#??X\b",
|
||||
"??o?'?B???k",
|
||||
"?of?7???",
|
||||
"? ?}&?#??X\b"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1320.8,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q27",
|
||||
"category": "associative",
|
||||
"query": "Grandma Lucas stroke February 2006 goodbye window",
|
||||
"returned": [
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-a99cefe3-5e83-4050-98d8-6c69f57c7c71",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325",
|
||||
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
|
||||
"art-4a99aa1a-489b-4b43-958b-25217adb1aad",
|
||||
"?ǚ?7??????"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1448.6,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q28",
|
||||
"category": "associative",
|
||||
"query": "Marines hernia sepsis medical ward",
|
||||
"returned": [
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325",
|
||||
"kn-58874a74-b96f-4883-9e08-45707f4bd3ee",
|
||||
"bl-33ecccc2-e37f-43db-91b3-c2a86f08aaac",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
|
||||
"art-e0bdf5d8-d163-491f-b649-453fee8b721d",
|
||||
"7?e?7???\f3?",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-9397c74b-35f3-4428-b4b0-5123353bbcd1",
|
||||
"?of?7???"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1107.9,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q29",
|
||||
"category": "associative",
|
||||
"query": "Sarah Bishop Dyer trailer performance",
|
||||
"returned": [
|
||||
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"art-4a99aa1a-489b-4b43-958b-25217adb1aad",
|
||||
"7?e?7???\f3?",
|
||||
"?of?7???",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
|
||||
"kn-58874a74-b96f-4883-9e08-45707f4bd3ee"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1151.1,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q30",
|
||||
"category": "associative",
|
||||
"query": "Swarm Architecture containment lateral worker",
|
||||
"returned": [
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"bl-9bde67c1-f0ba-4c3a-8fe5-de0deee0ce43",
|
||||
"8cbb60c5-4999-4ec1-8682-2592aedc4249",
|
||||
"bl-0fac287f-f4c0-4f15-bc4d-ff7f8a7af3ae",
|
||||
"7?e?7???\f3?",
|
||||
"kn-6f248a50-355b-47bb-aec8-e0e646a9b077",
|
||||
"? ?}&?#??X\b",
|
||||
"h??I?cB?Q??",
|
||||
"?of?7???",
|
||||
"? ?}&?#??X\b"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1154.5,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q31",
|
||||
"category": "associative",
|
||||
"query": "hope won inside the narrative preface",
|
||||
"returned": [
|
||||
"kn-5b606390-a52d-4ca2-8e0e-eba141d13440",
|
||||
"kn-e0423482-cfa5-4796-8689-8495c93b66bc",
|
||||
"knw-9e74ee95-ba7d-49b1-9262-977eae9729d1",
|
||||
"7?e?7???\f3?",
|
||||
"rQ??m?;?x?'",
|
||||
"?Q??m?;?u?'",
|
||||
"R^??m?;��?'",
|
||||
"?Q??m?;��`'",
|
||||
"? ?}&?#??X\b"
|
||||
],
|
||||
"n_returned": 9,
|
||||
"latency_ms": 1187.5,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q32",
|
||||
"category": "associative",
|
||||
"query": "man of the house six years old expectation",
|
||||
"returned": [
|
||||
"? ?}&?#??X\b",
|
||||
"kn-eb1b9e18-3dc6-4b9b-9cc6-86e0ae6b6be8",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-57b4c5e7-40c6-4c90-bf14-71841b0081d4",
|
||||
"knw-35940684-abc4-42f0-b942-818f66b1f69a",
|
||||
"art-4a99aa1a-489b-4b43-958b-25217adb1aad",
|
||||
"art-2fabd873-d787-49cb-ad30-d4ed9fcff8ef"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1413.3,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q33",
|
||||
"category": "nonsense",
|
||||
"query": "zqxjvw plimforth grebulon",
|
||||
"returned": [],
|
||||
"n_returned": 0,
|
||||
"latency_ms": 684.0,
|
||||
"error": null,
|
||||
"clean": true,
|
||||
"false_positives": 0
|
||||
},
|
||||
{
|
||||
"id": "q34",
|
||||
"category": "nonsense",
|
||||
"query": "flarnbistle quommetry",
|
||||
"returned": [],
|
||||
"n_returned": 0,
|
||||
"latency_ms": 444.0,
|
||||
"error": null,
|
||||
"clean": true,
|
||||
"false_positives": 0
|
||||
},
|
||||
{
|
||||
"id": "q35",
|
||||
"category": "nonsense",
|
||||
"query": "xxqzzt vurblenacht throom",
|
||||
"returned": [
|
||||
"art-4a99aa1a-489b-4b43-958b-25217adb1aad",
|
||||
"knw-920c891f-bb8c-48c4-9afc-018ef12dcdc4",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
|
||||
"bl-4476e856-c567-4b49-8ff7-d7dca3e5715e",
|
||||
"kn-66a21179-2adc-4b19-a109-880cf4674d7d",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 696.8,
|
||||
"error": null,
|
||||
"clean": false,
|
||||
"false_positives": 10
|
||||
},
|
||||
{
|
||||
"id": "q36",
|
||||
"category": "superseded",
|
||||
"query": "is the self-improvement architecture called DARMA or DHARMA",
|
||||
"returned": [
|
||||
"7?e?7???\f3?",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"?of?7???",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"mem-80d7416b-20e9-48a0-b176-b215527e2f56",
|
||||
"mem-f3b37427-b7d1-4f7e-b32c-0241a20ce8da",
|
||||
"art-80ca3d31-84dc-4502-83f4-538372b9764f"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1245.8,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.125,
|
||||
"outranks": true,
|
||||
"rank_correct": 8,
|
||||
"rank_stale": null
|
||||
},
|
||||
{
|
||||
"id": "q37",
|
||||
"category": "superseded",
|
||||
"query": "how many provisional patents does Will actually have",
|
||||
"returned": [
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"7?e?7???\f3?",
|
||||
"?of?7???",
|
||||
"?ǚ?7??????",
|
||||
"[?MO5????G",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1617.5,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0,
|
||||
"outranks": false,
|
||||
"rank_correct": null,
|
||||
"rank_stale": null
|
||||
},
|
||||
{
|
||||
"id": "q38",
|
||||
"category": "superseded",
|
||||
"query": "is MCP still the live integration layer",
|
||||
"returned": [
|
||||
"kn-5584ef9c-7f9d-4d7c-a10a-4ee6bc5cf356",
|
||||
"7?e?7???\f3?",
|
||||
"? ?}&?#??X\b",
|
||||
"%???2??jH??",
|
||||
"???Ͼd??W\b?",
|
||||
"??o?'?B???k",
|
||||
"? ?}&?#??X\b",
|
||||
"63307ac5-cf6b-46e0-8296-07503b461cfa",
|
||||
"? ?}&?#??X\b",
|
||||
"?of?7???"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 967.6,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0,
|
||||
"outranks": false,
|
||||
"rank_correct": null,
|
||||
"rank_stale": null
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,945 @@
|
||||
{
|
||||
"label": "main-r3",
|
||||
"soul_binary": "/private/tmp/claude-501/-Users-timlingo/82369039-a20e-4b5a-8a5e-28234a57b996/scratchpad/soul-main",
|
||||
"soul_md5": "caf822425540114984bfcd713ad37162",
|
||||
"corpus": "/Users/timlingo/neuron-memory-backups/snapshot-pre-repair-20260806.json",
|
||||
"corpus_nodes": 78768,
|
||||
"corpus_edges": 14214,
|
||||
"gold_set": "/Users/timlingo/Development/neuron-technologies/_wt-eval/tools/retrieval-eval/gold_set.json",
|
||||
"limit": 10,
|
||||
"port": 7896,
|
||||
"wall_clock_s": 45.7,
|
||||
"child_pid": 78750,
|
||||
"child_confirmed_dead": true,
|
||||
"aggregate": {
|
||||
"n_queries": 38,
|
||||
"n_scored": 35,
|
||||
"hit@5": 0.34285714285714286,
|
||||
"recall@5": 0.26947278911564626,
|
||||
"recall@10": 0.3333333333333333,
|
||||
"precision@5": 0.12000000000000001,
|
||||
"mrr@10": 0.2943197278911564,
|
||||
"nonsense_clean": "2/3",
|
||||
"superseded_outranks": "1/3",
|
||||
"latency_ms_p50": 1141.7,
|
||||
"latency_ms_p95": 1578.0,
|
||||
"latency_ms_max": 1645.5,
|
||||
"errors": 0,
|
||||
"by_category": {
|
||||
"associative": {
|
||||
"n": 6,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
"exact_rare": {
|
||||
"n": 6,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
"nonsense": {
|
||||
"n": 3,
|
||||
"clean": 2,
|
||||
"avg_false_positives": 3.3333333333333335
|
||||
},
|
||||
"paraphrase": {
|
||||
"n": 13,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
"phrase": {
|
||||
"n": 7,
|
||||
"hit@5": 0.8571428571428571,
|
||||
"recall@5": 0.4902210884353741,
|
||||
"recall@10": 0.6666666666666666,
|
||||
"mrr@10": 0.5965986394557822
|
||||
},
|
||||
"superseded": {
|
||||
"n": 3,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.3333333333333333,
|
||||
"mrr@10": 0.041666666666666664,
|
||||
"outranks": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"rows": [
|
||||
{
|
||||
"id": "q01",
|
||||
"category": "exact_rare",
|
||||
"query": "unjailbreakable",
|
||||
"returned": [
|
||||
"mem-7f61beb4-271c-4feb-9f6e-1c9c837a6226"
|
||||
],
|
||||
"n_returned": 1,
|
||||
"latency_ms": 237.9,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q02",
|
||||
"category": "exact_rare",
|
||||
"query": "engram-migrate",
|
||||
"returned": [
|
||||
"mem-6fdf6545-5e1a-43a9-8bdc-d2cd248146a5"
|
||||
],
|
||||
"n_returned": 1,
|
||||
"latency_ms": 272.4,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q03",
|
||||
"category": "exact_rare",
|
||||
"query": "cartabandonedevent",
|
||||
"returned": [
|
||||
"mem-1ba7c67d-85b9-4c2e-9fe2-39f8b0477091"
|
||||
],
|
||||
"n_returned": 1,
|
||||
"latency_ms": 231.8,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q04",
|
||||
"category": "exact_rare",
|
||||
"query": "pre-apprenticeship",
|
||||
"returned": [
|
||||
"mem-89c02aae-d3ca-43f9-9e5d-eb369896276c"
|
||||
],
|
||||
"n_returned": 1,
|
||||
"latency_ms": 231.9,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q05",
|
||||
"category": "exact_rare",
|
||||
"query": "inferencenodemanager",
|
||||
"returned": [
|
||||
"mem-73969486-143f-4431-b5e6-6845d1cc9848"
|
||||
],
|
||||
"n_returned": 1,
|
||||
"latency_ms": 262.6,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q06",
|
||||
"category": "exact_rare",
|
||||
"query": "clear-eyed",
|
||||
"returned": [
|
||||
"knw-c72597c5-c23d-4c08-8e9e-996dadf26a99"
|
||||
],
|
||||
"n_returned": 1,
|
||||
"latency_ms": 239.4,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q07",
|
||||
"category": "phrase",
|
||||
"query": "patterns not returns",
|
||||
"returned": [
|
||||
"kn-57b4c5e7-40c6-4c90-bf14-71841b0081d4",
|
||||
"?ǚ?7??????",
|
||||
"mem-a4a9dfc3-e40b-49b3-b1e1-060e8be2f482",
|
||||
"kn-5584ef9c-7f9d-4d7c-a10a-4ee6bc5cf356",
|
||||
"015644f5-8194-4af0-800d-dd4a0cd71396",
|
||||
"????7???Ջ3",
|
||||
"kn-d97920d0-1649-4223-9508-c0bb621e7fc0",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"art-d24fd6dd-2cda-4eed-92f3-67b535a0d71b",
|
||||
"7?e?7???\f3?"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 542.3,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 0.3333333333333333
|
||||
},
|
||||
{
|
||||
"id": "q08",
|
||||
"category": "phrase",
|
||||
"query": "thirty moves",
|
||||
"returned": [
|
||||
"knw-4aebd815-4eaf-49d7-954b-03595f3d48be",
|
||||
"knw-7902acca-604e-409b-8faf-ad85424211d0",
|
||||
"knw-2c46cfb4-6d4e-4822-8a1a-7d743c1e4329",
|
||||
"art-4a99aa1a-489b-4b43-958b-25217adb1aad",
|
||||
"knw-f671966c-3387-4848-abca-b5deec122e00",
|
||||
"knw-e94982a2-358d-4f2f-af31-8ee0fcec07c6",
|
||||
"Z[?<S???H??",
|
||||
"rQ??m?;?x?'",
|
||||
"kn-f230b362-b201-4402-9833-4160c89ab3d4",
|
||||
"kn-6061318f-046b-4935-907d-8eafdce14930"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 465.0,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 0.3125,
|
||||
"recall@10": 0.5,
|
||||
"precision@5": 1.0,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q09",
|
||||
"category": "phrase",
|
||||
"query": "Grandma Lucas",
|
||||
"returned": [
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c",
|
||||
"kn-a99cefe3-5e83-4050-98d8-6c69f57c7c71",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"766de879-f9d0-4a07-b6df-b43ee13763d8",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 470.1,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 0.3333333333333333,
|
||||
"recall@10": 0.5555555555555556,
|
||||
"precision@5": 0.6,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q10",
|
||||
"category": "phrase",
|
||||
"query": "Directed Harmonic",
|
||||
"returned": [
|
||||
"kn-5584ef9c-7f9d-4d7c-a10a-4ee6bc5cf356",
|
||||
"ԍ????X????",
|
||||
"bl-dcee1887-34c4-4ffa-9119-1e291685ba08",
|
||||
"?ǚ?7??????",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"knw-e24d6339-5ff3-4bed-ba53-707ffd0dc70a",
|
||||
"mem-7eeacad7-d7c2-4c2b-8348-19a59aa6dbaf",
|
||||
"????7???Ջ3",
|
||||
"??????X??2c",
|
||||
"g?e?7???'c?"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 441.0,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.1111111111111111,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.14285714285714285
|
||||
},
|
||||
{
|
||||
"id": "q11",
|
||||
"category": "phrase",
|
||||
"query": "Sarah Bishop",
|
||||
"returned": [
|
||||
"art-4a99aa1a-489b-4b43-958b-25217adb1aad",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"766de879-f9d0-4a07-b6df-b43ee13763d8",
|
||||
"mem-a9a9ce95-0d64-46eb-9db8-ff81d78ade35",
|
||||
"mem-b8ecd23e-77ce-42f7-984c-f51453fec16d"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 455.9,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 0.5,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 0.2
|
||||
},
|
||||
{
|
||||
"id": "q12",
|
||||
"category": "phrase",
|
||||
"query": "Directed Autonomous Runtime Modification",
|
||||
"returned": [
|
||||
"bl-5b17bd3b-0c41-46cb-a710-6fa4429692ff",
|
||||
"bl-145a0985-2382-400f-a7c5-c335c5e30a72",
|
||||
"mem-82b93b21-a865-410f-9ec1-fc54121d9bb5",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"mem-e6327f52-2bda-4ce7-9471-2fffd1e172de",
|
||||
"7?e?7???\f3?",
|
||||
"?of?7???",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b"
|
||||
],
|
||||
"n_returned": 9,
|
||||
"latency_ms": 816.2,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 0.2857142857142857,
|
||||
"recall@10": 0.5,
|
||||
"precision@5": 0.8,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q13",
|
||||
"category": "phrase",
|
||||
"query": "zero-knowledge encrypted backup",
|
||||
"returned": [
|
||||
"7774a16c-1027-4e3b-a21e-67f1f95a4acd",
|
||||
"deda48cd-5e1a-46cb-bd43-8016afdb3a8a",
|
||||
"mem-dba009a2-d2ea-4f5a-b9e8-0f04bc9ab32f",
|
||||
"mem-a3c97012-5fa3-4915-a839-2c75c72005e0",
|
||||
"mem-7cd90611-88a3-423d-a38a-0db2812952fa",
|
||||
"bl-07375bf9-a169-42cd-adb3-7d32b25982f0",
|
||||
"bl-ec84b63d-b278-4944-8d7f-4aa7a51c0315",
|
||||
"7?e?7???\f3?",
|
||||
"?of?7???",
|
||||
"? ?}&?#??X\b"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 678.3,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 0.5
|
||||
},
|
||||
{
|
||||
"id": "q14",
|
||||
"category": "paraphrase",
|
||||
"query": "the elderly relative who passed while he stayed away",
|
||||
"returned": [
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"art-4a99aa1a-489b-4b43-958b-25217adb1aad",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"????7???Ջ3",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1564.4,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q15",
|
||||
"category": "paraphrase",
|
||||
"query": "a soldier sidelined by illness who refused to quit",
|
||||
"returned": [
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325",
|
||||
"art-2fabd873-d787-49cb-ad30-d4ed9fcff8ef",
|
||||
"art-2f29ad36-6ee6-4a0e-8d72-0eaf7d12d3a9",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-a31e1001-342e-4deb-a2e6-6d02d1f22dee",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"knw-9e74ee95-ba7d-49b1-9262-977eae9729d1",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1645.5,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q16",
|
||||
"category": "paraphrase",
|
||||
"query": "choosing an uncomfortable fact over a pleasant fiction",
|
||||
"returned": [
|
||||
"7?e?7???\f3?",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-f8974b26-78a6-4aad-b893-19a73b20013d",
|
||||
"?of?7???",
|
||||
"????7???Ջ3",
|
||||
"kn-d97920d0-1649-4223-9508-c0bb621e7fc0",
|
||||
"kn-57b4c5e7-40c6-4c90-bf14-71841b0081d4",
|
||||
"kn-9397c74b-35f3-4428-b4b0-5123353bbcd1",
|
||||
"kn-81c24d13-a73b-4767-819c-dafaacc1498e",
|
||||
"? ?}&?#??X\b"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1320.9,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q17",
|
||||
"category": "paraphrase",
|
||||
"query": "a tight payload beats a bloated one",
|
||||
"returned": [
|
||||
"kn-d7c1e0fb-fa59-46d3-b4c9-a0d1d437a491",
|
||||
"7?e?7???\f3?",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-e8423822-eacf-4029-aa7b-10d4d28d621e",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"??o?'?B???k",
|
||||
"kn-9397c74b-35f3-4428-b4b0-5123353bbcd1",
|
||||
"? ?}&?#??X\b",
|
||||
"?of?7???"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1029.9,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q18",
|
||||
"category": "paraphrase",
|
||||
"query": "if you are able and nobody is coming the job is yours",
|
||||
"returned": [
|
||||
"7?e?7???\f3?",
|
||||
"?of?7???",
|
||||
"imp-dce1da0f-8776-4a9e-972b-33411a7ca138",
|
||||
"kn-5b606390-a52d-4ca2-8e0e-eba141d13440",
|
||||
"kn-83bb86c6-521d-416c-a86e-6e29c2d8f102",
|
||||
"kn-f8974b26-78a6-4aad-b893-19a73b20013d",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b"
|
||||
],
|
||||
"n_returned": 9,
|
||||
"latency_ms": 1347.6,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q19",
|
||||
"category": "paraphrase",
|
||||
"query": "learning is the wealth creditors cannot seize",
|
||||
"returned": [
|
||||
"kn-5584ef9c-7f9d-4d7c-a10a-4ee6bc5cf356",
|
||||
"knw-7902acca-604e-409b-8faf-ad85424211d0",
|
||||
"knw-e24d6339-5ff3-4bed-ba53-707ffd0dc70a",
|
||||
"kn-57b4c5e7-40c6-4c90-bf14-71841b0081d4",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"7?e?7???\f3?",
|
||||
"??o?'?B???k",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-0625e393-067c-4bba-8389-7e1b79265142",
|
||||
"ע?RGk?\tH(?"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1220.4,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q20",
|
||||
"category": "paraphrase",
|
||||
"query": "reliability proven by track record not assertion",
|
||||
"returned": [
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"7?e?7???\f3?",
|
||||
"?of?7???",
|
||||
"art-2fabd873-d787-49cb-ad30-d4ed9fcff8ef",
|
||||
"kn-5584ef9c-7f9d-4d7c-a10a-4ee6bc5cf356"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1560.9,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q21",
|
||||
"category": "paraphrase",
|
||||
"query": "boundaries that enable instead of confine",
|
||||
"returned": [
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"??????X??2c",
|
||||
"ԍ????X????",
|
||||
"dR????X?-?S",
|
||||
"kn-5584ef9c-7f9d-4d7c-a10a-4ee6bc5cf356",
|
||||
"dz????Xƹ?i",
|
||||
"kn-d7c1e0fb-fa59-46d3-b4c9-a0d1d437a491"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1305.3,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q22",
|
||||
"category": "paraphrase",
|
||||
"query": "what shifts tells you where to cut a system apart",
|
||||
"returned": [
|
||||
"7?e?7???\f3?",
|
||||
"kn-9397c74b-35f3-4428-b4b0-5123353bbcd1",
|
||||
"?of?7???",
|
||||
"kn-f8974b26-78a6-4aad-b893-19a73b20013d",
|
||||
"knw-9e74ee95-ba7d-49b1-9262-977eae9729d1",
|
||||
"dR????X?-?S",
|
||||
"dz????Xƹ?i",
|
||||
"ԍ????X????",
|
||||
"??????X??2c",
|
||||
"kn-d7c1e0fb-fa59-46d3-b4c9-a0d1d437a491"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1578.0,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q23",
|
||||
"category": "paraphrase",
|
||||
"query": "a mind that compounds instead of resetting each day",
|
||||
"returned": [
|
||||
"????7???Ջ3",
|
||||
"kn-5584ef9c-7f9d-4d7c-a10a-4ee6bc5cf356",
|
||||
"?ǚ?7??????",
|
||||
"7?e?7???\f3?",
|
||||
"??f?7???",
|
||||
"? ?}&?#??X\b",
|
||||
"%???2??jH??",
|
||||
"kn-e8423822-eacf-4029-aa7b-10d4d28d621e",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-9397c74b-35f3-4428-b4b0-5123353bbcd1"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1449.2,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q24",
|
||||
"category": "paraphrase",
|
||||
"query": "loved for the unedited self and not the polished exterior",
|
||||
"returned": [
|
||||
"mem-bbb126a1-b297-42bb-86be-796871829c94",
|
||||
"mem-45022957-2d78-48aa-a714-16d6eca52e0f",
|
||||
"art-4a99aa1a-489b-4b43-958b-25217adb1aad",
|
||||
"knw-35940684-abc4-42f0-b942-818f66b1f69a",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
|
||||
"7?e?7???\f3?",
|
||||
"? ?}&?#??X\b",
|
||||
"'?T?a\"B~-?8"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1489.4,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q25",
|
||||
"category": "paraphrase",
|
||||
"query": "cheerfulness you arrive at instead of assuming",
|
||||
"returned": [
|
||||
"015644f5-8194-4af0-800d-dd4a0cd71396",
|
||||
"?ǚ?7??????",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325",
|
||||
"7?e?7???\f3?",
|
||||
"kn-e8423822-eacf-4029-aa7b-10d4d28d621e",
|
||||
"??S?7???",
|
||||
"? ?}&?#??X\b",
|
||||
"??f?7???",
|
||||
"??S?7???",
|
||||
"knw-5578cb21-e899-4822-b7f4-0d96fa094e3d"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1186.5,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q26",
|
||||
"category": "paraphrase",
|
||||
"query": "a childhood offering no solid foundation to inherit",
|
||||
"returned": [
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"7?e?7???\f3?",
|
||||
"kn-e8423822-eacf-4029-aa7b-10d4d28d621e",
|
||||
"? ?}&?#??X\b",
|
||||
"??o?'?B???k",
|
||||
"?of?7???",
|
||||
"? ?}&?#??X\b"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1309.1,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q27",
|
||||
"category": "associative",
|
||||
"query": "Grandma Lucas stroke February 2006 goodbye window",
|
||||
"returned": [
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-a99cefe3-5e83-4050-98d8-6c69f57c7c71",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325",
|
||||
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
|
||||
"art-4a99aa1a-489b-4b43-958b-25217adb1aad",
|
||||
"?ǚ?7??????"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1427.2,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q28",
|
||||
"category": "associative",
|
||||
"query": "Marines hernia sepsis medical ward",
|
||||
"returned": [
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325",
|
||||
"kn-58874a74-b96f-4883-9e08-45707f4bd3ee",
|
||||
"bl-33ecccc2-e37f-43db-91b3-c2a86f08aaac",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
|
||||
"art-e0bdf5d8-d163-491f-b649-453fee8b721d",
|
||||
"7?e?7???\f3?",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-9397c74b-35f3-4428-b4b0-5123353bbcd1",
|
||||
"?of?7???"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1081.3,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q29",
|
||||
"category": "associative",
|
||||
"query": "Sarah Bishop Dyer trailer performance",
|
||||
"returned": [
|
||||
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"art-4a99aa1a-489b-4b43-958b-25217adb1aad",
|
||||
"7?e?7???\f3?",
|
||||
"?of?7???",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
|
||||
"kn-58874a74-b96f-4883-9e08-45707f4bd3ee"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1144.2,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q30",
|
||||
"category": "associative",
|
||||
"query": "Swarm Architecture containment lateral worker",
|
||||
"returned": [
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"bl-9bde67c1-f0ba-4c3a-8fe5-de0deee0ce43",
|
||||
"8cbb60c5-4999-4ec1-8682-2592aedc4249",
|
||||
"bl-0fac287f-f4c0-4f15-bc4d-ff7f8a7af3ae",
|
||||
"7?e?7???\f3?",
|
||||
"kn-6f248a50-355b-47bb-aec8-e0e646a9b077",
|
||||
"? ?}&?#??X\b",
|
||||
"h??I?cB?Q??",
|
||||
"?of?7???",
|
||||
"? ?}&?#??X\b"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1141.7,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q31",
|
||||
"category": "associative",
|
||||
"query": "hope won inside the narrative preface",
|
||||
"returned": [
|
||||
"kn-5b606390-a52d-4ca2-8e0e-eba141d13440",
|
||||
"kn-e0423482-cfa5-4796-8689-8495c93b66bc",
|
||||
"knw-9e74ee95-ba7d-49b1-9262-977eae9729d1",
|
||||
"7?e?7???\f3?",
|
||||
"rQ??m?;?x?'",
|
||||
"?Q??m?;?u?'",
|
||||
"R^??m?;��?'",
|
||||
"?Q??m?;��`'",
|
||||
"? ?}&?#??X\b"
|
||||
],
|
||||
"n_returned": 9,
|
||||
"latency_ms": 1171.7,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q32",
|
||||
"category": "associative",
|
||||
"query": "man of the house six years old expectation",
|
||||
"returned": [
|
||||
"? ?}&?#??X\b",
|
||||
"kn-eb1b9e18-3dc6-4b9b-9cc6-86e0ae6b6be8",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-57b4c5e7-40c6-4c90-bf14-71841b0081d4",
|
||||
"knw-35940684-abc4-42f0-b942-818f66b1f69a",
|
||||
"art-4a99aa1a-489b-4b43-958b-25217adb1aad",
|
||||
"art-2fabd873-d787-49cb-ad30-d4ed9fcff8ef"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1388.1,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q33",
|
||||
"category": "nonsense",
|
||||
"query": "zqxjvw plimforth grebulon",
|
||||
"returned": [],
|
||||
"n_returned": 0,
|
||||
"latency_ms": 659.0,
|
||||
"error": null,
|
||||
"clean": true,
|
||||
"false_positives": 0
|
||||
},
|
||||
{
|
||||
"id": "q34",
|
||||
"category": "nonsense",
|
||||
"query": "flarnbistle quommetry",
|
||||
"returned": [],
|
||||
"n_returned": 0,
|
||||
"latency_ms": 432.5,
|
||||
"error": null,
|
||||
"clean": true,
|
||||
"false_positives": 0
|
||||
},
|
||||
{
|
||||
"id": "q35",
|
||||
"category": "nonsense",
|
||||
"query": "xxqzzt vurblenacht throom",
|
||||
"returned": [
|
||||
"art-4a99aa1a-489b-4b43-958b-25217adb1aad",
|
||||
"knw-920c891f-bb8c-48c4-9afc-018ef12dcdc4",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
|
||||
"bl-4476e856-c567-4b49-8ff7-d7dca3e5715e",
|
||||
"kn-66a21179-2adc-4b19-a109-880cf4674d7d",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 673.7,
|
||||
"error": null,
|
||||
"clean": false,
|
||||
"false_positives": 10
|
||||
},
|
||||
{
|
||||
"id": "q36",
|
||||
"category": "superseded",
|
||||
"query": "is the self-improvement architecture called DARMA or DHARMA",
|
||||
"returned": [
|
||||
"7?e?7???\f3?",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"?of?7???",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"mem-80d7416b-20e9-48a0-b176-b215527e2f56",
|
||||
"mem-f3b37427-b7d1-4f7e-b32c-0241a20ce8da",
|
||||
"art-80ca3d31-84dc-4502-83f4-538372b9764f"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1254.6,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.125,
|
||||
"outranks": true,
|
||||
"rank_correct": 8,
|
||||
"rank_stale": null
|
||||
},
|
||||
{
|
||||
"id": "q37",
|
||||
"category": "superseded",
|
||||
"query": "how many provisional patents does Will actually have",
|
||||
"returned": [
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"7?e?7???\f3?",
|
||||
"?of?7???",
|
||||
"?ǚ?7??????",
|
||||
"[?MO5????G",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1626.6,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0,
|
||||
"outranks": false,
|
||||
"rank_correct": null,
|
||||
"rank_stale": null
|
||||
},
|
||||
{
|
||||
"id": "q38",
|
||||
"category": "superseded",
|
||||
"query": "is MCP still the live integration layer",
|
||||
"returned": [
|
||||
"kn-5584ef9c-7f9d-4d7c-a10a-4ee6bc5cf356",
|
||||
"7?e?7???\f3?",
|
||||
"? ?}&?#??X\b",
|
||||
"%???2??jH??",
|
||||
"???Ͼd??W\b?",
|
||||
"??o?'?B???k",
|
||||
"? ?}&?#??X\b",
|
||||
"63307ac5-cf6b-46e0-8296-07503b461cfa",
|
||||
"? ?}&?#??X\b",
|
||||
"?of?7???"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 950.9,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0,
|
||||
"outranks": false,
|
||||
"rank_correct": null,
|
||||
"rank_stale": null
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,945 @@
|
||||
{
|
||||
"label": "main-r1",
|
||||
"soul_binary": "/private/tmp/claude-501/-Users-timlingo/82369039-a20e-4b5a-8a5e-28234a57b996/scratchpad/soul-main",
|
||||
"soul_md5": "caf822425540114984bfcd713ad37162",
|
||||
"corpus": "/Users/timlingo/neuron-memory-backups/snapshot-pre-repair-20260806.json",
|
||||
"corpus_nodes": 78768,
|
||||
"corpus_edges": 14214,
|
||||
"gold_set": "/Users/timlingo/Development/neuron-technologies/_wt-eval/tools/retrieval-eval/gold_set.json",
|
||||
"limit": 10,
|
||||
"port": 7893,
|
||||
"wall_clock_s": 45.9,
|
||||
"child_pid": 78554,
|
||||
"child_confirmed_dead": true,
|
||||
"aggregate": {
|
||||
"n_queries": 38,
|
||||
"n_scored": 35,
|
||||
"hit@5": 0.34285714285714286,
|
||||
"recall@5": 0.26947278911564626,
|
||||
"recall@10": 0.3333333333333333,
|
||||
"precision@5": 0.12000000000000001,
|
||||
"mrr@10": 0.2943197278911564,
|
||||
"nonsense_clean": "2/3",
|
||||
"superseded_outranks": "1/3",
|
||||
"latency_ms_p50": 1140.4,
|
||||
"latency_ms_p95": 1584.1,
|
||||
"latency_ms_max": 1627.6,
|
||||
"errors": 0,
|
||||
"by_category": {
|
||||
"associative": {
|
||||
"n": 6,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
"exact_rare": {
|
||||
"n": 6,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
"nonsense": {
|
||||
"n": 3,
|
||||
"clean": 2,
|
||||
"avg_false_positives": 3.3333333333333335
|
||||
},
|
||||
"paraphrase": {
|
||||
"n": 13,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
"phrase": {
|
||||
"n": 7,
|
||||
"hit@5": 0.8571428571428571,
|
||||
"recall@5": 0.4902210884353741,
|
||||
"recall@10": 0.6666666666666666,
|
||||
"mrr@10": 0.5965986394557822
|
||||
},
|
||||
"superseded": {
|
||||
"n": 3,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.3333333333333333,
|
||||
"mrr@10": 0.041666666666666664,
|
||||
"outranks": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"rows": [
|
||||
{
|
||||
"id": "q01",
|
||||
"category": "exact_rare",
|
||||
"query": "unjailbreakable",
|
||||
"returned": [
|
||||
"mem-7f61beb4-271c-4feb-9f6e-1c9c837a6226"
|
||||
],
|
||||
"n_returned": 1,
|
||||
"latency_ms": 240.2,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q02",
|
||||
"category": "exact_rare",
|
||||
"query": "engram-migrate",
|
||||
"returned": [
|
||||
"mem-6fdf6545-5e1a-43a9-8bdc-d2cd248146a5"
|
||||
],
|
||||
"n_returned": 1,
|
||||
"latency_ms": 271.3,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q03",
|
||||
"category": "exact_rare",
|
||||
"query": "cartabandonedevent",
|
||||
"returned": [
|
||||
"mem-1ba7c67d-85b9-4c2e-9fe2-39f8b0477091"
|
||||
],
|
||||
"n_returned": 1,
|
||||
"latency_ms": 232.0,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q04",
|
||||
"category": "exact_rare",
|
||||
"query": "pre-apprenticeship",
|
||||
"returned": [
|
||||
"mem-89c02aae-d3ca-43f9-9e5d-eb369896276c"
|
||||
],
|
||||
"n_returned": 1,
|
||||
"latency_ms": 227.8,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q05",
|
||||
"category": "exact_rare",
|
||||
"query": "inferencenodemanager",
|
||||
"returned": [
|
||||
"mem-73969486-143f-4431-b5e6-6845d1cc9848"
|
||||
],
|
||||
"n_returned": 1,
|
||||
"latency_ms": 259.1,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q06",
|
||||
"category": "exact_rare",
|
||||
"query": "clear-eyed",
|
||||
"returned": [
|
||||
"knw-c72597c5-c23d-4c08-8e9e-996dadf26a99"
|
||||
],
|
||||
"n_returned": 1,
|
||||
"latency_ms": 237.4,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q07",
|
||||
"category": "phrase",
|
||||
"query": "patterns not returns",
|
||||
"returned": [
|
||||
"kn-57b4c5e7-40c6-4c90-bf14-71841b0081d4",
|
||||
"?ǚ?7??????",
|
||||
"mem-a4a9dfc3-e40b-49b3-b1e1-060e8be2f482",
|
||||
"kn-5584ef9c-7f9d-4d7c-a10a-4ee6bc5cf356",
|
||||
"015644f5-8194-4af0-800d-dd4a0cd71396",
|
||||
"????7???Ջ3",
|
||||
"kn-d97920d0-1649-4223-9508-c0bb621e7fc0",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"art-d24fd6dd-2cda-4eed-92f3-67b535a0d71b",
|
||||
"7?e?7???\f3?"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 543.7,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 0.3333333333333333
|
||||
},
|
||||
{
|
||||
"id": "q08",
|
||||
"category": "phrase",
|
||||
"query": "thirty moves",
|
||||
"returned": [
|
||||
"knw-4aebd815-4eaf-49d7-954b-03595f3d48be",
|
||||
"knw-7902acca-604e-409b-8faf-ad85424211d0",
|
||||
"knw-2c46cfb4-6d4e-4822-8a1a-7d743c1e4329",
|
||||
"art-4a99aa1a-489b-4b43-958b-25217adb1aad",
|
||||
"knw-f671966c-3387-4848-abca-b5deec122e00",
|
||||
"knw-e94982a2-358d-4f2f-af31-8ee0fcec07c6",
|
||||
"Z[?<S???H??",
|
||||
"rQ??m?;?x?'",
|
||||
"kn-f230b362-b201-4402-9833-4160c89ab3d4",
|
||||
"kn-6061318f-046b-4935-907d-8eafdce14930"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 467.1,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 0.3125,
|
||||
"recall@10": 0.5,
|
||||
"precision@5": 1.0,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q09",
|
||||
"category": "phrase",
|
||||
"query": "Grandma Lucas",
|
||||
"returned": [
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c",
|
||||
"kn-a99cefe3-5e83-4050-98d8-6c69f57c7c71",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"766de879-f9d0-4a07-b6df-b43ee13763d8",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 475.2,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 0.3333333333333333,
|
||||
"recall@10": 0.5555555555555556,
|
||||
"precision@5": 0.6,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q10",
|
||||
"category": "phrase",
|
||||
"query": "Directed Harmonic",
|
||||
"returned": [
|
||||
"kn-5584ef9c-7f9d-4d7c-a10a-4ee6bc5cf356",
|
||||
"ԍ????X????",
|
||||
"bl-dcee1887-34c4-4ffa-9119-1e291685ba08",
|
||||
"?ǚ?7??????",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"knw-e24d6339-5ff3-4bed-ba53-707ffd0dc70a",
|
||||
"mem-7eeacad7-d7c2-4c2b-8348-19a59aa6dbaf",
|
||||
"????7???Ջ3",
|
||||
"??????X??2c",
|
||||
"g?e?7???'c?"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 449.6,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.1111111111111111,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.14285714285714285
|
||||
},
|
||||
{
|
||||
"id": "q11",
|
||||
"category": "phrase",
|
||||
"query": "Sarah Bishop",
|
||||
"returned": [
|
||||
"art-4a99aa1a-489b-4b43-958b-25217adb1aad",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"766de879-f9d0-4a07-b6df-b43ee13763d8",
|
||||
"mem-a9a9ce95-0d64-46eb-9db8-ff81d78ade35",
|
||||
"mem-b8ecd23e-77ce-42f7-984c-f51453fec16d"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 463.9,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 0.5,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 0.2
|
||||
},
|
||||
{
|
||||
"id": "q12",
|
||||
"category": "phrase",
|
||||
"query": "Directed Autonomous Runtime Modification",
|
||||
"returned": [
|
||||
"bl-5b17bd3b-0c41-46cb-a710-6fa4429692ff",
|
||||
"bl-145a0985-2382-400f-a7c5-c335c5e30a72",
|
||||
"mem-82b93b21-a865-410f-9ec1-fc54121d9bb5",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"mem-e6327f52-2bda-4ce7-9471-2fffd1e172de",
|
||||
"7?e?7???\f3?",
|
||||
"?of?7???",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b"
|
||||
],
|
||||
"n_returned": 9,
|
||||
"latency_ms": 821.5,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 0.2857142857142857,
|
||||
"recall@10": 0.5,
|
||||
"precision@5": 0.8,
|
||||
"mrr@10": 1.0
|
||||
},
|
||||
{
|
||||
"id": "q13",
|
||||
"category": "phrase",
|
||||
"query": "zero-knowledge encrypted backup",
|
||||
"returned": [
|
||||
"7774a16c-1027-4e3b-a21e-67f1f95a4acd",
|
||||
"deda48cd-5e1a-46cb-bd43-8016afdb3a8a",
|
||||
"mem-dba009a2-d2ea-4f5a-b9e8-0f04bc9ab32f",
|
||||
"mem-a3c97012-5fa3-4915-a839-2c75c72005e0",
|
||||
"mem-7cd90611-88a3-423d-a38a-0db2812952fa",
|
||||
"bl-07375bf9-a169-42cd-adb3-7d32b25982f0",
|
||||
"bl-ec84b63d-b278-4944-8d7f-4aa7a51c0315",
|
||||
"7?e?7???\f3?",
|
||||
"?of?7???",
|
||||
"? ?}&?#??X\b"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 688.0,
|
||||
"error": null,
|
||||
"hit@5": 1.0,
|
||||
"recall@5": 1.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.2,
|
||||
"mrr@10": 0.5
|
||||
},
|
||||
{
|
||||
"id": "q14",
|
||||
"category": "paraphrase",
|
||||
"query": "the elderly relative who passed while he stayed away",
|
||||
"returned": [
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"art-4a99aa1a-489b-4b43-958b-25217adb1aad",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"????7???Ջ3",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1559.5,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q15",
|
||||
"category": "paraphrase",
|
||||
"query": "a soldier sidelined by illness who refused to quit",
|
||||
"returned": [
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325",
|
||||
"art-2fabd873-d787-49cb-ad30-d4ed9fcff8ef",
|
||||
"art-2f29ad36-6ee6-4a0e-8d72-0eaf7d12d3a9",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-a31e1001-342e-4deb-a2e6-6d02d1f22dee",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"knw-9e74ee95-ba7d-49b1-9262-977eae9729d1",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1627.6,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q16",
|
||||
"category": "paraphrase",
|
||||
"query": "choosing an uncomfortable fact over a pleasant fiction",
|
||||
"returned": [
|
||||
"7?e?7???\f3?",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-f8974b26-78a6-4aad-b893-19a73b20013d",
|
||||
"?of?7???",
|
||||
"????7???Ջ3",
|
||||
"kn-d97920d0-1649-4223-9508-c0bb621e7fc0",
|
||||
"kn-57b4c5e7-40c6-4c90-bf14-71841b0081d4",
|
||||
"kn-9397c74b-35f3-4428-b4b0-5123353bbcd1",
|
||||
"kn-81c24d13-a73b-4767-819c-dafaacc1498e",
|
||||
"? ?}&?#??X\b"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1317.2,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q17",
|
||||
"category": "paraphrase",
|
||||
"query": "a tight payload beats a bloated one",
|
||||
"returned": [
|
||||
"kn-d7c1e0fb-fa59-46d3-b4c9-a0d1d437a491",
|
||||
"7?e?7???\f3?",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-e8423822-eacf-4029-aa7b-10d4d28d621e",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"??o?'?B???k",
|
||||
"kn-9397c74b-35f3-4428-b4b0-5123353bbcd1",
|
||||
"? ?}&?#??X\b",
|
||||
"?of?7???"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1055.2,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q18",
|
||||
"category": "paraphrase",
|
||||
"query": "if you are able and nobody is coming the job is yours",
|
||||
"returned": [
|
||||
"7?e?7???\f3?",
|
||||
"?of?7???",
|
||||
"imp-dce1da0f-8776-4a9e-972b-33411a7ca138",
|
||||
"kn-5b606390-a52d-4ca2-8e0e-eba141d13440",
|
||||
"kn-83bb86c6-521d-416c-a86e-6e29c2d8f102",
|
||||
"kn-f8974b26-78a6-4aad-b893-19a73b20013d",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b"
|
||||
],
|
||||
"n_returned": 9,
|
||||
"latency_ms": 1352.5,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q19",
|
||||
"category": "paraphrase",
|
||||
"query": "learning is the wealth creditors cannot seize",
|
||||
"returned": [
|
||||
"kn-5584ef9c-7f9d-4d7c-a10a-4ee6bc5cf356",
|
||||
"knw-7902acca-604e-409b-8faf-ad85424211d0",
|
||||
"knw-e24d6339-5ff3-4bed-ba53-707ffd0dc70a",
|
||||
"kn-57b4c5e7-40c6-4c90-bf14-71841b0081d4",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"7?e?7???\f3?",
|
||||
"??o?'?B???k",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-0625e393-067c-4bba-8389-7e1b79265142",
|
||||
"ע?RGk?\tH(?"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1213.0,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q20",
|
||||
"category": "paraphrase",
|
||||
"query": "reliability proven by track record not assertion",
|
||||
"returned": [
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"7?e?7???\f3?",
|
||||
"?of?7???",
|
||||
"art-2fabd873-d787-49cb-ad30-d4ed9fcff8ef",
|
||||
"kn-5584ef9c-7f9d-4d7c-a10a-4ee6bc5cf356"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1545.8,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q21",
|
||||
"category": "paraphrase",
|
||||
"query": "boundaries that enable instead of confine",
|
||||
"returned": [
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"??????X??2c",
|
||||
"ԍ????X????",
|
||||
"dR????X?-?S",
|
||||
"kn-5584ef9c-7f9d-4d7c-a10a-4ee6bc5cf356",
|
||||
"dz????Xƹ?i",
|
||||
"kn-d7c1e0fb-fa59-46d3-b4c9-a0d1d437a491"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1327.3,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q22",
|
||||
"category": "paraphrase",
|
||||
"query": "what shifts tells you where to cut a system apart",
|
||||
"returned": [
|
||||
"7?e?7???\f3?",
|
||||
"kn-9397c74b-35f3-4428-b4b0-5123353bbcd1",
|
||||
"?of?7???",
|
||||
"kn-f8974b26-78a6-4aad-b893-19a73b20013d",
|
||||
"knw-9e74ee95-ba7d-49b1-9262-977eae9729d1",
|
||||
"dR????X?-?S",
|
||||
"dz????Xƹ?i",
|
||||
"ԍ????X????",
|
||||
"??????X??2c",
|
||||
"kn-d7c1e0fb-fa59-46d3-b4c9-a0d1d437a491"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1584.1,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q23",
|
||||
"category": "paraphrase",
|
||||
"query": "a mind that compounds instead of resetting each day",
|
||||
"returned": [
|
||||
"????7???Ջ3",
|
||||
"kn-5584ef9c-7f9d-4d7c-a10a-4ee6bc5cf356",
|
||||
"?ǚ?7??????",
|
||||
"7?e?7???\f3?",
|
||||
"??f?7???",
|
||||
"? ?}&?#??X\b",
|
||||
"%???2??jH??",
|
||||
"kn-e8423822-eacf-4029-aa7b-10d4d28d621e",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-9397c74b-35f3-4428-b4b0-5123353bbcd1"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1432.6,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q24",
|
||||
"category": "paraphrase",
|
||||
"query": "loved for the unedited self and not the polished exterior",
|
||||
"returned": [
|
||||
"mem-bbb126a1-b297-42bb-86be-796871829c94",
|
||||
"mem-45022957-2d78-48aa-a714-16d6eca52e0f",
|
||||
"art-4a99aa1a-489b-4b43-958b-25217adb1aad",
|
||||
"knw-35940684-abc4-42f0-b942-818f66b1f69a",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325",
|
||||
"art-0f0277a1-4a8e-4645-95dd-fa379976f31c",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
|
||||
"7?e?7???\f3?",
|
||||
"? ?}&?#??X\b",
|
||||
"'?T?a\"B~-?8"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1505.5,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q25",
|
||||
"category": "paraphrase",
|
||||
"query": "cheerfulness you arrive at instead of assuming",
|
||||
"returned": [
|
||||
"015644f5-8194-4af0-800d-dd4a0cd71396",
|
||||
"?ǚ?7??????",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325",
|
||||
"7?e?7???\f3?",
|
||||
"kn-e8423822-eacf-4029-aa7b-10d4d28d621e",
|
||||
"??S?7???",
|
||||
"? ?}&?#??X\b",
|
||||
"??f?7???",
|
||||
"??S?7???",
|
||||
"knw-5578cb21-e899-4822-b7f4-0d96fa094e3d"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1201.1,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q26",
|
||||
"category": "paraphrase",
|
||||
"query": "a childhood offering no solid foundation to inherit",
|
||||
"returned": [
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"7?e?7???\f3?",
|
||||
"kn-e8423822-eacf-4029-aa7b-10d4d28d621e",
|
||||
"? ?}&?#??X\b",
|
||||
"??o?'?B???k",
|
||||
"?of?7???",
|
||||
"? ?}&?#??X\b"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1303.3,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q27",
|
||||
"category": "associative",
|
||||
"query": "Grandma Lucas stroke February 2006 goodbye window",
|
||||
"returned": [
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-a99cefe3-5e83-4050-98d8-6c69f57c7c71",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325",
|
||||
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
|
||||
"art-4a99aa1a-489b-4b43-958b-25217adb1aad",
|
||||
"?ǚ?7??????"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1416.3,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q28",
|
||||
"category": "associative",
|
||||
"query": "Marines hernia sepsis medical ward",
|
||||
"returned": [
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325",
|
||||
"kn-58874a74-b96f-4883-9e08-45707f4bd3ee",
|
||||
"bl-33ecccc2-e37f-43db-91b3-c2a86f08aaac",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
|
||||
"art-e0bdf5d8-d163-491f-b649-453fee8b721d",
|
||||
"7?e?7???\f3?",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-9397c74b-35f3-4428-b4b0-5123353bbcd1",
|
||||
"?of?7???"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1090.3,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q29",
|
||||
"category": "associative",
|
||||
"query": "Sarah Bishop Dyer trailer performance",
|
||||
"returned": [
|
||||
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"art-4a99aa1a-489b-4b43-958b-25217adb1aad",
|
||||
"7?e?7???\f3?",
|
||||
"?of?7???",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
|
||||
"kn-58874a74-b96f-4883-9e08-45707f4bd3ee"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1167.7,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q30",
|
||||
"category": "associative",
|
||||
"query": "Swarm Architecture containment lateral worker",
|
||||
"returned": [
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3",
|
||||
"bl-9bde67c1-f0ba-4c3a-8fe5-de0deee0ce43",
|
||||
"8cbb60c5-4999-4ec1-8682-2592aedc4249",
|
||||
"bl-0fac287f-f4c0-4f15-bc4d-ff7f8a7af3ae",
|
||||
"7?e?7???\f3?",
|
||||
"kn-6f248a50-355b-47bb-aec8-e0e646a9b077",
|
||||
"? ?}&?#??X\b",
|
||||
"h??I?cB?Q??",
|
||||
"?of?7???",
|
||||
"? ?}&?#??X\b"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1140.4,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q31",
|
||||
"category": "associative",
|
||||
"query": "hope won inside the narrative preface",
|
||||
"returned": [
|
||||
"kn-5b606390-a52d-4ca2-8e0e-eba141d13440",
|
||||
"kn-e0423482-cfa5-4796-8689-8495c93b66bc",
|
||||
"knw-9e74ee95-ba7d-49b1-9262-977eae9729d1",
|
||||
"7?e?7???\f3?",
|
||||
"rQ??m?;?x?'",
|
||||
"?Q??m?;?u?'",
|
||||
"R^??m?;��?'",
|
||||
"?Q??m?;��`'",
|
||||
"? ?}&?#??X\b"
|
||||
],
|
||||
"n_returned": 9,
|
||||
"latency_ms": 1157.6,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q32",
|
||||
"category": "associative",
|
||||
"query": "man of the house six years old expectation",
|
||||
"returned": [
|
||||
"? ?}&?#??X\b",
|
||||
"kn-eb1b9e18-3dc6-4b9b-9cc6-86e0ae6b6be8",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"kn-57b4c5e7-40c6-4c90-bf14-71841b0081d4",
|
||||
"knw-35940684-abc4-42f0-b942-818f66b1f69a",
|
||||
"art-4a99aa1a-489b-4b43-958b-25217adb1aad",
|
||||
"art-2fabd873-d787-49cb-ad30-d4ed9fcff8ef"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1379.7,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0
|
||||
},
|
||||
{
|
||||
"id": "q33",
|
||||
"category": "nonsense",
|
||||
"query": "zqxjvw plimforth grebulon",
|
||||
"returned": [],
|
||||
"n_returned": 0,
|
||||
"latency_ms": 677.2,
|
||||
"error": null,
|
||||
"clean": true,
|
||||
"false_positives": 0
|
||||
},
|
||||
{
|
||||
"id": "q34",
|
||||
"category": "nonsense",
|
||||
"query": "flarnbistle quommetry",
|
||||
"returned": [],
|
||||
"n_returned": 0,
|
||||
"latency_ms": 443.2,
|
||||
"error": null,
|
||||
"clean": true,
|
||||
"false_positives": 0
|
||||
},
|
||||
{
|
||||
"id": "q35",
|
||||
"category": "nonsense",
|
||||
"query": "xxqzzt vurblenacht throom",
|
||||
"returned": [
|
||||
"art-4a99aa1a-489b-4b43-958b-25217adb1aad",
|
||||
"knw-920c891f-bb8c-48c4-9afc-018ef12dcdc4",
|
||||
"art-79042b8b-6192-440f-90b0-60708f7e6325",
|
||||
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
|
||||
"bl-4476e856-c567-4b49-8ff7-d7dca3e5715e",
|
||||
"kn-66a21179-2adc-4b19-a109-880cf4674d7d",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 679.8,
|
||||
"error": null,
|
||||
"clean": false,
|
||||
"false_positives": 10
|
||||
},
|
||||
{
|
||||
"id": "q36",
|
||||
"category": "superseded",
|
||||
"query": "is the self-improvement architecture called DARMA or DHARMA",
|
||||
"returned": [
|
||||
"7?e?7???\f3?",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"?of?7???",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"mem-80d7416b-20e9-48a0-b176-b215527e2f56",
|
||||
"mem-f3b37427-b7d1-4f7e-b32c-0241a20ce8da",
|
||||
"art-80ca3d31-84dc-4502-83f4-538372b9764f"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1245.4,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 1.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.125,
|
||||
"outranks": true,
|
||||
"rank_correct": 8,
|
||||
"rank_stale": null
|
||||
},
|
||||
{
|
||||
"id": "q37",
|
||||
"category": "superseded",
|
||||
"query": "how many provisional patents does Will actually have",
|
||||
"returned": [
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"? ?}&?#??X\b",
|
||||
"7?e?7???\f3?",
|
||||
"?of?7???",
|
||||
"?ǚ?7??????",
|
||||
"[?MO5????G",
|
||||
"art-ee615cdb-e599-423d-9a4d-977859390ed3"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 1618.4,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0,
|
||||
"outranks": false,
|
||||
"rank_correct": null,
|
||||
"rank_stale": null
|
||||
},
|
||||
{
|
||||
"id": "q38",
|
||||
"category": "superseded",
|
||||
"query": "is MCP still the live integration layer",
|
||||
"returned": [
|
||||
"kn-5584ef9c-7f9d-4d7c-a10a-4ee6bc5cf356",
|
||||
"7?e?7???\f3?",
|
||||
"? ?}&?#??X\b",
|
||||
"%???2??jH??",
|
||||
"???Ͼd??W\b?",
|
||||
"??o?'?B???k",
|
||||
"? ?}&?#??X\b",
|
||||
"63307ac5-cf6b-46e0-8296-07503b461cfa",
|
||||
"? ?}&?#??X\b",
|
||||
"?of?7???"
|
||||
],
|
||||
"n_returned": 10,
|
||||
"latency_ms": 956.7,
|
||||
"error": null,
|
||||
"hit@5": 0.0,
|
||||
"recall@5": 0.0,
|
||||
"recall@10": 0.0,
|
||||
"precision@5": 0.0,
|
||||
"mrr@10": 0.0,
|
||||
"outranks": false,
|
||||
"rank_correct": null,
|
||||
"rank_stale": null
|
||||
}
|
||||
]
|
||||
}
|
||||
Executable
+98
@@ -0,0 +1,98 @@
|
||||
#!/usr/bin/env bash
|
||||
# run_comparison.sh — the whole harness, end to end, from two git refs.
|
||||
#
|
||||
# Builds a soul from each ref, boots each on its own throwaway port with its own
|
||||
# throwaway HOME and its own disposable copy of the corpus, runs the gold set N
|
||||
# times per ref, and prints the comparison with its noise threshold.
|
||||
#
|
||||
# SAFETY: never touches ~/.neuron, /Applications/Neuron*, ~/neuron-dev-stack, or
|
||||
# any running service. Sources are exported with `git archive` into a scratch
|
||||
# dir, so no worktree or branch state is mutated either. Ports are checked
|
||||
# against the live set before anything boots. Every soul this script starts is
|
||||
# killed and confirmed dead by run_eval.py; the sweep at the end is a backstop.
|
||||
#
|
||||
# usage:
|
||||
# run_comparison.sh [--baseline main] [--candidate feat/recall-through-activation]
|
||||
# [--repeats 3] [--corpus <snapshot.json>] [--repo <path>]
|
||||
set -euo pipefail
|
||||
|
||||
BASELINE="main"
|
||||
CANDIDATE="feat/recall-through-activation"
|
||||
REPEATS=3
|
||||
CORPUS="$HOME/neuron-memory-backups/snapshot-pre-repair-20260806.json"
|
||||
REPO="$HOME/Development/neuron"
|
||||
BASE_PORT=7893
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--baseline) BASELINE="$2"; shift 2 ;;
|
||||
--candidate) CANDIDATE="$2"; shift 2 ;;
|
||||
--repeats) REPEATS="$2"; shift 2 ;;
|
||||
--corpus) CORPUS="$2"; shift 2 ;;
|
||||
--repo) REPO="$2"; shift 2 ;;
|
||||
*) echo "unknown arg: $1" >&2; exit 2 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
WORK="$(mktemp -d "${TMPDIR:-/tmp}/retrieval-eval.XXXXXX")"
|
||||
trap 'rm -rf "$WORK"' EXIT
|
||||
|
||||
[ -f "$CORPUS" ] || { echo "no corpus at $CORPUS" >&2; exit 2; }
|
||||
echo "corpus: $CORPUS ($(du -h "$CORPUS" | cut -f1))"
|
||||
|
||||
slug() { printf '%s' "$1" | tr '/' '-'; }
|
||||
|
||||
build_ref() { # ref -> binary path
|
||||
local ref="$1" out="$WORK/soul-$(slug "$1")"
|
||||
local src="$WORK/src-$(slug "$1")"
|
||||
mkdir -p "$src"
|
||||
git -C "$REPO" archive "$ref" | tar -x -C "$src"
|
||||
"$HERE/build-soul.sh" "$src" "$out" >&2
|
||||
printf '%s' "$out"
|
||||
}
|
||||
|
||||
echo "== building $BASELINE =="
|
||||
BIN_A="$(build_ref "$BASELINE")"
|
||||
echo "== building $CANDIDATE =="
|
||||
BIN_B="$(build_ref "$CANDIDATE")"
|
||||
|
||||
echo "== validating the gold set against this corpus =="
|
||||
python3 "$HERE/build_gold_set.py" "$CORPUS" --check
|
||||
|
||||
port=$BASE_PORT
|
||||
run_one() { # binary label out
|
||||
echo "== $2 =="
|
||||
python3 "$HERE/run_eval.py" --soul "$1" --corpus "$CORPUS" --label "$2" \
|
||||
--port "$port" --out "$3"
|
||||
port=$((port + 1))
|
||||
}
|
||||
|
||||
A_MAIN="$WORK/results-a-1.json"; B_MAIN="$WORK/results-b-1.json"
|
||||
A_REP=(); B_REP=()
|
||||
for i in $(seq 1 "$REPEATS"); do
|
||||
a="$WORK/results-a-$i.json"; b="$WORK/results-b-$i.json"
|
||||
run_one "$BIN_A" "$(slug "$BASELINE")-r$i" "$a"
|
||||
run_one "$BIN_B" "$(slug "$CANDIDATE")-r$i" "$b"
|
||||
[ "$i" -gt 1 ] && { A_REP+=("$a"); B_REP+=("$b"); }
|
||||
done
|
||||
|
||||
cp "$A_MAIN" "$HERE/results-$(slug "$BASELINE").json"
|
||||
cp "$B_MAIN" "$HERE/results-$(slug "$CANDIDATE").json"
|
||||
|
||||
echo
|
||||
python3 "$HERE/compare.py" \
|
||||
--baseline "$A_MAIN" --candidate "$B_MAIN" \
|
||||
${A_REP[@]+--repeats-baseline "${A_REP[@]}"} \
|
||||
${B_REP[@]+--repeats-candidate "${B_REP[@]}"} \
|
||||
--out "$HERE/comparison-$(slug "$BASELINE")-vs-$(slug "$CANDIDATE").json"
|
||||
|
||||
# Backstop: run_eval.py kills and confirms its own child, but a crashed run
|
||||
# could leak one. Leaving a soul running is how the live engine got squeezed.
|
||||
STRAY=$(pgrep -f "$WORK/soul-" || true)
|
||||
if [ -n "$STRAY" ]; then
|
||||
echo "!! stray eval souls, killing: $STRAY" >&2
|
||||
kill -9 $STRAY 2>/dev/null || true
|
||||
fi
|
||||
pgrep -f "$WORK/soul-" >/dev/null && { echo "!! STILL RUNNING" >&2; exit 5; }
|
||||
echo "process check: no eval souls running"
|
||||
Executable
+398
@@ -0,0 +1,398 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
run_eval.py — measure one soul build's retrieval against the gold set.
|
||||
|
||||
WHAT IT MEASURES, AND WHY IT BOOTS A REAL SOUL
|
||||
The point is Will's designed retrieval — spreading activation over the
|
||||
weighted directed graph with four-factor multiplicative scoring — not a
|
||||
Python re-implementation of it. A re-implementation would measure my
|
||||
reading of the design; booting the compiled binary measures the design. So
|
||||
this harness compiles the actual `soul.el` amalgam (build-soul.sh) and asks
|
||||
it over HTTP, exactly as the MCP wrapper and the app do.
|
||||
|
||||
SAFETY — read this before changing anything here
|
||||
* Boots on a THROWAWAY port with a THROWAWAY $HOME and a THROWAWAY COPY of
|
||||
the corpus. Refuses to use 7770 / 8742 / 7779 / 17779 / 7771.
|
||||
* ENGRAM_URL / SOUL_ENGRAM_URL are UNSET and SOUL_ISE_URL is pinned to a
|
||||
dead port. This is not belt-and-braces: the periodic engram sync resolves
|
||||
its source as env(SOUL_ISE_URL) -> state -> DEFAULT http://localhost:8742,
|
||||
so leaving it unset makes an "isolated" run silently pull the operator's
|
||||
LIVE brain. (Learned the hard way on 2026-08-03; see the same note in
|
||||
scripts/verify-soul-contract.sh.)
|
||||
* Every process this file starts is tracked and killed in a finally block,
|
||||
then CONFIRMED dead by pid probe, and the confirmation is written into the
|
||||
results file. A run that cannot confirm its child is dead exits non-zero.
|
||||
* Activation is a STATEFUL read by design (patent claim 29: traversal
|
||||
updates last-activation and increments activation counts). The corpus copy
|
||||
is therefore per-run and disposable, and every run starts from a byte-
|
||||
identical copy so two configurations see the same starting graph.
|
||||
|
||||
usage:
|
||||
python3 run_eval.py --soul <binary> --corpus <snapshot.json> --label main \
|
||||
[--port 7893] [--gold gold_set.json] [--limit 10] [--out results-main.json]
|
||||
"""
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
import signal
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import time
|
||||
import urllib.error
|
||||
import urllib.parse
|
||||
import urllib.request
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
FORBIDDEN_PORTS = {7770, 8742, 7779, 17779, 7771, 8080}
|
||||
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# metrics
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
def recall_at_k(returned, relevant, k):
|
||||
if not relevant:
|
||||
return None
|
||||
return len(set(returned[:k]) & set(relevant)) / len(relevant)
|
||||
|
||||
|
||||
def hit_at_k(returned, relevant, k):
|
||||
if not relevant:
|
||||
return None
|
||||
return 1.0 if set(returned[:k]) & set(relevant) else 0.0
|
||||
|
||||
|
||||
def precision_at_k(returned, relevant, k):
|
||||
"""Fixed denominator k, as in docs/research/graphrag_eval/score.py.
|
||||
|
||||
Fixed denominator penalises an empty result and a page of junk equally,
|
||||
which is what we want: a retriever that returns nothing is not 'precise'.
|
||||
"""
|
||||
if not relevant:
|
||||
return None
|
||||
return len(set(returned[:k]) & set(relevant)) / k
|
||||
|
||||
|
||||
def mrr(returned, relevant, k):
|
||||
if not relevant:
|
||||
return None
|
||||
rel = set(relevant)
|
||||
for i, nid in enumerate(returned[:k], start=1):
|
||||
if nid in rel:
|
||||
return 1.0 / i
|
||||
return 0.0
|
||||
|
||||
|
||||
def mean(vals):
|
||||
vals = [v for v in vals if v is not None]
|
||||
return sum(vals) / len(vals) if vals else 0.0
|
||||
|
||||
|
||||
def pct(vals):
|
||||
return f"{100 * mean(vals):.1f}%"
|
||||
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# soul lifecycle
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
class Soul:
|
||||
def __init__(self, binary, corpus, port, verbose=True):
|
||||
if port in FORBIDDEN_PORTS:
|
||||
raise SystemExit(f"REFUSING: port {port} is a live service port.")
|
||||
self.binary = os.path.abspath(binary)
|
||||
self.corpus = os.path.abspath(corpus)
|
||||
self.port = port
|
||||
self.verbose = verbose
|
||||
self.home = None
|
||||
self.proc = None
|
||||
self.pid = None
|
||||
self.log = None
|
||||
self.confirmed_dead = None
|
||||
|
||||
@property
|
||||
def base(self):
|
||||
return f"http://127.0.0.1:{self.port}"
|
||||
|
||||
def start(self, boot_timeout=180):
|
||||
self.home = tempfile.mkdtemp(prefix="retrieval-eval-home.")
|
||||
snap = os.path.join(self.home, "corpus.json")
|
||||
t0 = time.time()
|
||||
shutil.copyfile(self.corpus, snap) # per-run disposable copy, never the source
|
||||
self.log = os.path.join(self.home, "soul.log")
|
||||
|
||||
env = {k: v for k, v in os.environ.items()
|
||||
if k not in ("ENGRAM_URL", "ENGRAM_API_KEY", "SOUL_ENGRAM_URL",
|
||||
"ANTHROPIC_API_KEY", "NEURON_LLM_API_KEY", "SOUL_IDENTITY",
|
||||
"SOUL_API_KEY")}
|
||||
env.update({
|
||||
"HOME": self.home,
|
||||
"NEURON_PORT": str(self.port),
|
||||
"SOUL_CGI_ID": f"ntn-retrieval-eval-{os.getpid()}",
|
||||
"SOUL_ENGRAM_PATH": snap,
|
||||
"NEURON_API_URL": "http://127.0.0.1:9", # dead port
|
||||
"SOUL_ISE_URL": "http://127.0.0.1:9", # dead port — see SAFETY above
|
||||
# Park the background loops for an hour so heartbeat/consolidation
|
||||
# cannot mutate the graph between queries and make runs unrepeatable.
|
||||
"SOUL_TICK_MS": "3600000",
|
||||
"SOUL_HEARTBEAT_MS": "3600000",
|
||||
"SOUL_REFRESH_MS": "3600000",
|
||||
})
|
||||
with open(self.log, "wb") as lf:
|
||||
self.proc = subprocess.Popen([self.binary], env=env, stdout=lf, stderr=lf,
|
||||
start_new_session=True)
|
||||
self.pid = self.proc.pid
|
||||
if self.verbose:
|
||||
print(f" booted pid={self.pid} port={self.port} home={self.home}")
|
||||
|
||||
deadline = time.time() + boot_timeout
|
||||
while time.time() < deadline:
|
||||
if self.proc.poll() is not None:
|
||||
raise RuntimeError(f"soul exited during boot: {self._log_tail()}")
|
||||
rss = self._rss_kb()
|
||||
if rss and rss > 6 * 1024 * 1024:
|
||||
self.stop()
|
||||
raise RuntimeError(f"soul RSS {rss}KB > 6GB — aborted")
|
||||
try:
|
||||
with urllib.request.urlopen(f"{self.base}/health", timeout=2) as r:
|
||||
if r.status == 200:
|
||||
if self.verbose:
|
||||
print(f" healthy in {time.time() - t0:.1f}s, RSS={self._rss_kb()}KB")
|
||||
return
|
||||
except Exception:
|
||||
pass
|
||||
time.sleep(0.5)
|
||||
self.stop()
|
||||
raise RuntimeError(f"soul never healthy on {self.base}: {self._log_tail()}")
|
||||
|
||||
def _rss_kb(self):
|
||||
try:
|
||||
out = subprocess.run(["ps", "-o", "rss=", "-p", str(self.pid)],
|
||||
capture_output=True, text=True, timeout=5).stdout.strip()
|
||||
return int(out) if out else None
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
def _log_tail(self, n=15):
|
||||
try:
|
||||
with open(self.log, encoding="utf-8", errors="replace") as fh:
|
||||
return "\n".join(fh.read().splitlines()[-n:])
|
||||
except Exception:
|
||||
return "(no log)"
|
||||
|
||||
def recall(self, query, limit, timeout=60):
|
||||
url = f"{self.base}/api/neuron/recall?query={urllib.parse.quote(query)}&limit={limit}"
|
||||
t0 = time.perf_counter()
|
||||
try:
|
||||
with urllib.request.urlopen(url, timeout=timeout) as r:
|
||||
raw = r.read().decode("utf-8", "replace")
|
||||
ms = (time.perf_counter() - t0) * 1000
|
||||
except Exception as exc:
|
||||
return [], (time.perf_counter() - t0) * 1000, f"{type(exc).__name__}: {exc}"
|
||||
try:
|
||||
arr = json.loads(raw)
|
||||
except Exception:
|
||||
return [], ms, f"unparseable response ({len(raw)}B)"
|
||||
if not isinstance(arr, list):
|
||||
return [], ms, f"non-array response: {str(arr)[:120]}"
|
||||
ids = [x.get("id") for x in arr if isinstance(x, dict) and x.get("id")]
|
||||
return ids, ms, None
|
||||
|
||||
def stop(self):
|
||||
"""Kill and CONFIRM. A test process that outlives its test is a bug."""
|
||||
if self.pid is None:
|
||||
self.confirmed_dead = True
|
||||
return True
|
||||
for sig in (signal.SIGTERM, signal.SIGKILL):
|
||||
try:
|
||||
os.kill(self.pid, sig)
|
||||
except ProcessLookupError:
|
||||
break
|
||||
except Exception:
|
||||
pass
|
||||
for _ in range(20):
|
||||
try:
|
||||
os.kill(self.pid, 0)
|
||||
except ProcessLookupError:
|
||||
break
|
||||
time.sleep(0.1)
|
||||
else:
|
||||
continue
|
||||
break
|
||||
try:
|
||||
self.proc.wait(timeout=5)
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
os.kill(self.pid, 0)
|
||||
self.confirmed_dead = False
|
||||
except ProcessLookupError:
|
||||
self.confirmed_dead = True
|
||||
if self.verbose:
|
||||
print(f" pid {self.pid}: {'CONFIRMED DEAD' if self.confirmed_dead else 'STILL ALIVE'}")
|
||||
if self.home and os.path.isdir(self.home):
|
||||
shutil.rmtree(self.home, ignore_errors=True)
|
||||
return self.confirmed_dead
|
||||
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# eval
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
def evaluate(soul, gold, limit):
|
||||
rows = []
|
||||
for q in gold["queries"]:
|
||||
ids, ms, err = soul.recall(q["query"], limit)
|
||||
rel = q.get("relevant") or []
|
||||
row = {
|
||||
"id": q["id"],
|
||||
"category": q["category"],
|
||||
"query": q["query"],
|
||||
"returned": ids,
|
||||
"n_returned": len(ids),
|
||||
"latency_ms": round(ms, 1),
|
||||
"error": err,
|
||||
}
|
||||
if q.get("expect_empty"):
|
||||
row["clean"] = (len(ids) == 0)
|
||||
row["false_positives"] = len(ids)
|
||||
else:
|
||||
row["hit@5"] = hit_at_k(ids, rel, 5)
|
||||
row["recall@5"] = recall_at_k(ids, rel, 5)
|
||||
row["recall@10"] = recall_at_k(ids, rel, 10)
|
||||
row["precision@5"] = precision_at_k(ids, rel, 5)
|
||||
row["mrr@10"] = mrr(ids, rel, 10)
|
||||
if q.get("must_outrank"):
|
||||
correct, stale = q["must_outrank"]
|
||||
ic = ids.index(correct) if correct in ids else None
|
||||
istale = ids.index(stale) if stale in ids else None
|
||||
# Correct must be present AND above the stale node. A run that
|
||||
# returns neither is NOT a pass: the corrected fact is what the
|
||||
# user needed.
|
||||
row["outranks"] = (ic is not None) and (istale is None or ic < istale)
|
||||
row["rank_correct"] = None if ic is None else ic + 1
|
||||
row["rank_stale"] = None if istale is None else istale + 1
|
||||
rows.append(row)
|
||||
return rows
|
||||
|
||||
|
||||
def aggregate(rows):
|
||||
scored = [r for r in rows if "hit@5" in r]
|
||||
nonsense = [r for r in rows if "clean" in r]
|
||||
outrank = [r for r in rows if "outranks" in r]
|
||||
lat = sorted(r["latency_ms"] for r in rows)
|
||||
agg = {
|
||||
"n_queries": len(rows),
|
||||
"n_scored": len(scored),
|
||||
"hit@5": mean([r["hit@5"] for r in scored]),
|
||||
"recall@5": mean([r["recall@5"] for r in scored]),
|
||||
"recall@10": mean([r["recall@10"] for r in scored]),
|
||||
"precision@5": mean([r["precision@5"] for r in scored]),
|
||||
"mrr@10": mean([r["mrr@10"] for r in scored]),
|
||||
"nonsense_clean": f"{sum(1 for r in nonsense if r['clean'])}/{len(nonsense)}",
|
||||
"superseded_outranks": f"{sum(1 for r in outrank if r['outranks'])}/{len(outrank)}",
|
||||
"latency_ms_p50": lat[len(lat) // 2] if lat else 0,
|
||||
"latency_ms_p95": lat[max(0, int(len(lat) * 0.95) - 1)] if lat else 0,
|
||||
"latency_ms_max": lat[-1] if lat else 0,
|
||||
"errors": sum(1 for r in rows if r["error"]),
|
||||
"by_category": {},
|
||||
}
|
||||
cats = sorted({r["category"] for r in rows})
|
||||
for c in cats:
|
||||
cr = [r for r in rows if r["category"] == c]
|
||||
if c == "nonsense":
|
||||
agg["by_category"][c] = {
|
||||
"n": len(cr),
|
||||
"clean": sum(1 for r in cr if r["clean"]),
|
||||
"avg_false_positives": mean([float(r["false_positives"]) for r in cr]),
|
||||
}
|
||||
else:
|
||||
e = {
|
||||
"n": len(cr),
|
||||
"hit@5": mean([r.get("hit@5") for r in cr]),
|
||||
"recall@5": mean([r.get("recall@5") for r in cr]),
|
||||
"recall@10": mean([r.get("recall@10") for r in cr]),
|
||||
"mrr@10": mean([r.get("mrr@10") for r in cr]),
|
||||
}
|
||||
if c == "superseded":
|
||||
e["outranks"] = sum(1 for r in cr if r.get("outranks"))
|
||||
agg["by_category"][c] = e
|
||||
return agg
|
||||
|
||||
|
||||
def print_table(label, agg):
|
||||
print(f"\n=== {label} ===")
|
||||
print(f" queries {agg['n_queries']} ({agg['n_scored']} scored + "
|
||||
f"{agg['n_queries'] - agg['n_scored']} control) · errors {agg['errors']}")
|
||||
print(f" {'hit@5':>12} {'recall@5':>10} {'recall@10':>10} {'prec@5':>9} {'MRR@10':>9}")
|
||||
print(f" {pct([agg['hit@5']]):>12} {pct([agg['recall@5']]):>10} {pct([agg['recall@10']]):>10} "
|
||||
f"{pct([agg['precision@5']]):>9} {agg['mrr@10']:>9.3f}")
|
||||
print(f" nonsense clean {agg['nonsense_clean']} · superseded outranks {agg['superseded_outranks']}")
|
||||
print(f" latency ms p50 {agg['latency_ms_p50']:.0f} · p95 {agg['latency_ms_p95']:.0f} "
|
||||
f"· max {agg['latency_ms_max']:.0f}")
|
||||
print(f"\n {'category':14} {'n':>3} {'hit@5':>8} {'recall@5':>9} {'recall@10':>10} {'MRR@10':>8}")
|
||||
for c, e in agg["by_category"].items():
|
||||
if c == "nonsense":
|
||||
print(f" {c:14} {e['n']:>3} {'clean ' + str(e['clean']) + '/' + str(e['n']):>8}"
|
||||
f"{'':>9} {'':>10} {'avg FP ' + format(e['avg_false_positives'], '.1f'):>8}")
|
||||
else:
|
||||
extra = f" outranks {e['outranks']}/{e['n']}" if "outranks" in e else ""
|
||||
print(f" {c:14} {e['n']:>3} {pct([e['hit@5']]):>8} {pct([e['recall@5']]):>9} "
|
||||
f"{pct([e['recall@10']]):>10} {e['mrr@10']:>8.3f}{extra}")
|
||||
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument("--soul", required=True)
|
||||
ap.add_argument("--corpus", required=True)
|
||||
ap.add_argument("--label", required=True)
|
||||
ap.add_argument("--gold", default=os.path.join(HERE, "gold_set.json"))
|
||||
ap.add_argument("--port", type=int, default=7893)
|
||||
ap.add_argument("--limit", type=int, default=10)
|
||||
ap.add_argument("--out", default=None)
|
||||
args = ap.parse_args()
|
||||
|
||||
with open(args.gold, encoding="utf-8") as fh:
|
||||
gold = json.load(fh)
|
||||
print(f"[{args.label}] soul={os.path.basename(args.soul)} "
|
||||
f"corpus={os.path.basename(args.corpus)} gold={len(gold['queries'])}q limit={args.limit}")
|
||||
|
||||
soul = Soul(args.soul, args.corpus, args.port)
|
||||
rows = []
|
||||
started = time.time()
|
||||
try:
|
||||
soul.start()
|
||||
rows = evaluate(soul, gold, args.limit)
|
||||
finally:
|
||||
dead = soul.stop()
|
||||
|
||||
agg = aggregate(rows)
|
||||
print_table(args.label, agg)
|
||||
|
||||
out = args.out or os.path.join(HERE, f"results-{args.label}.json")
|
||||
doc = {
|
||||
"label": args.label,
|
||||
"soul_binary": os.path.abspath(args.soul),
|
||||
"soul_md5": subprocess.run(["md5", "-q", args.soul], capture_output=True,
|
||||
text=True).stdout.strip(),
|
||||
"corpus": os.path.abspath(args.corpus),
|
||||
"corpus_nodes": gold.get("corpus_nodes"),
|
||||
"corpus_edges": gold.get("corpus_edges"),
|
||||
"gold_set": os.path.abspath(args.gold),
|
||||
"limit": args.limit,
|
||||
"port": args.port,
|
||||
"wall_clock_s": round(time.time() - started, 1),
|
||||
"child_pid": soul.pid,
|
||||
"child_confirmed_dead": soul.confirmed_dead,
|
||||
"aggregate": agg,
|
||||
"rows": rows,
|
||||
}
|
||||
with open(out, "w", encoding="utf-8") as fh:
|
||||
json.dump(doc, fh, indent=1, ensure_ascii=False)
|
||||
print(f"\nwrote {out}")
|
||||
if not dead:
|
||||
print("FATAL: child process could not be confirmed dead", file=sys.stderr)
|
||||
sys.exit(4)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
# El Compiler Release v1.0.0 — 2026-05-02
|
||||
|
||||
## Components
|
||||
- `bootstrap.py` — El language compiler (Python, recursive descent parser, emits C)
|
||||
- `el_runtime.c` — El runtime (C, HTTP server, engram, DHARMA, LLM chain)
|
||||
- `el_runtime.h` — Runtime public API header
|
||||
|
||||
## Changes in this release
|
||||
|
||||
### Critical bug fixes
|
||||
- `state_set`/`state_get` are now thread-safe (pthread_mutex). Was racing across 64 worker threads.
|
||||
- `looks_like_string` threshold raised from 1,000,000 to 4GB. Unix timestamps were being dereferenced as heap pointers.
|
||||
- `fs_read` guards against negative `ftell` result (pipe/special file overflow).
|
||||
|
||||
### Engram architecture (major)
|
||||
- Two-layer activation: `background_activation` (Layer 1, broad fan-out) + `working_memory_weight` (Layer 2, executive filter)
|
||||
- Inhibitory edges: `EngramEdge.inhibitory` flag suppresses working memory promotion without affecting background activation
|
||||
- Suppression memory: `suppression_count` — nodes activated-but-suppressed accumulate pressure toward breakthrough
|
||||
- Temporal decay: `temporal_decay_rate`, `created_at`, `last_activated_at`, `activation_count` on EngramNode
|
||||
- Per-type activation thresholds (Safety: 0.05, Canonical: 0.15, Lesson: 0.25, Note: 0.40)
|
||||
- Temporal range query: `engram_query_range(start_ms, end_ms)`
|
||||
- Layered consciousness: `EngramLayer` struct, `layer_id` on nodes and edges, `EngramStore.layers[]`
|
||||
- Layer 0 override pass: safety layer fires last and cannot be suppressed
|
||||
|
||||
## SHA256
|
||||
bootstrap.py
|
||||
el_runtime.c
|
||||
el_runtime.h
|
||||
+12671
File diff suppressed because it is too large
Load Diff
+786
@@ -0,0 +1,786 @@
|
||||
/*
|
||||
* el_runtime.h — El language C runtime header
|
||||
*
|
||||
* Declares all built-in functions available to compiled El programs.
|
||||
* Include this in every generated .c file.
|
||||
*
|
||||
* Value model:
|
||||
* All El values are represented as el_val_t (= int64_t).
|
||||
* On 64-bit systems a pointer fits in int64_t.
|
||||
* String values are cast: (el_val_t)(uintptr_t)"hello"
|
||||
* Integer values are stored directly.
|
||||
* This lets arithmetic work naturally while still passing strings around.
|
||||
*
|
||||
* Type conventions (El -> C):
|
||||
* String -> el_val_t (holds const char* via uintptr_t cast)
|
||||
* Int -> el_val_t
|
||||
* Bool -> el_val_t (0 = false, nonzero = true)
|
||||
* Any -> el_val_t
|
||||
* Void -> void
|
||||
*
|
||||
* Macros for convenience:
|
||||
* EL_STR(s) cast string literal to el_val_t
|
||||
* EL_CSTR(v) cast el_val_t back to const char*
|
||||
* EL_INT(v) identity — el_val_t is already int64_t
|
||||
*
|
||||
* Link requirements:
|
||||
* -lcurl — required for the HTTP client (http_get, http_post, llm_*).
|
||||
* -lpthread — required for the HTTP server (one detached thread per
|
||||
* connection, capped at 64 concurrent).
|
||||
* -loqs — optional; required only when liboqs is installed and the
|
||||
* pq_* / sha3_256_hex entry points are needed. Detected at
|
||||
* compile time via __has_include(<oqs/oqs.h>).
|
||||
* -lcrypto — optional; pulled in alongside -loqs. Used for X25519 in
|
||||
* pq_hybrid_* and HKDF-SHA256 derivation.
|
||||
*
|
||||
* Canonical compile command:
|
||||
* cc -std=c11 -I el-compiler/runtime -lcurl -lpthread \
|
||||
* -o <out> <prog>.c el-compiler/runtime/el_runtime.c
|
||||
*
|
||||
* With liboqs (post-quantum stack):
|
||||
* cc -std=c11 -I el-compiler/runtime -lcurl -lpthread -loqs -lcrypto \
|
||||
* -o <out> <prog>.c el-compiler/runtime/el_runtime.c
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef int64_t el_val_t;
|
||||
|
||||
#define EL_STR(s) ((el_val_t)(uintptr_t)(s))
|
||||
#define EL_CSTR(v) ((const char*)(uintptr_t)(v))
|
||||
#define EL_INT(v) (v)
|
||||
#define EL_NULL ((el_val_t)0)
|
||||
|
||||
/* Float values share the el_val_t (int64) slot via a bit-cast.
|
||||
* The codegen emits Float literals as `el_from_float(<dbl>)` so the
|
||||
* underlying bits represent the IEEE 754 double. Float-aware builtins
|
||||
* (math, format, json) round-trip via these helpers. */
|
||||
static inline double el_to_float(el_val_t v) {
|
||||
union { int64_t i; double f; } u;
|
||||
u.i = (int64_t)v;
|
||||
return u.f;
|
||||
}
|
||||
|
||||
static inline el_val_t el_from_float(double f) {
|
||||
union { double f; int64_t i; } u;
|
||||
u.f = f;
|
||||
return (el_val_t)u.i;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ── I/O ──────────────────────────────────────────────────────────────────── */
|
||||
|
||||
void println(el_val_t s);
|
||||
void print(el_val_t s);
|
||||
el_val_t readline(void);
|
||||
|
||||
/* ── String builtins ─────────────────────────────────────────────────────── */
|
||||
|
||||
el_val_t el_str_concat(el_val_t a, el_val_t b);
|
||||
el_val_t str_eq(el_val_t a, el_val_t b);
|
||||
el_val_t str_starts_with(el_val_t s, el_val_t prefix);
|
||||
el_val_t str_ends_with(el_val_t s, el_val_t suffix);
|
||||
el_val_t str_len(el_val_t s);
|
||||
el_val_t str_concat(el_val_t a, el_val_t b);
|
||||
el_val_t int_to_str(el_val_t n);
|
||||
el_val_t str_to_int(el_val_t s);
|
||||
el_val_t str_slice(el_val_t s, el_val_t start, el_val_t end);
|
||||
el_val_t str_contains(el_val_t s, el_val_t sub);
|
||||
el_val_t str_replace(el_val_t s, el_val_t from, el_val_t to);
|
||||
el_val_t str_to_upper(el_val_t s);
|
||||
el_val_t str_to_lower(el_val_t s);
|
||||
el_val_t str_trim(el_val_t s);
|
||||
|
||||
/* ── Math ────────────────────────────────────────────────────────────────── */
|
||||
|
||||
el_val_t el_abs(el_val_t n);
|
||||
el_val_t el_max(el_val_t a, el_val_t b);
|
||||
el_val_t el_min(el_val_t a, el_val_t b);
|
||||
|
||||
/* ── Refcount (ARC) ──────────────────────────────────────────────────────────
|
||||
* Lists and Maps carry a refcount. Strings and ints do not — el_retain and
|
||||
* el_release are safe no-ops on non-refcounted values (they sniff a magic
|
||||
* header at offset 0 and only act if the magic matches).
|
||||
*
|
||||
* Codegen emits these at let-binding shadowing, function entry (params), and
|
||||
* function exit (locals other than the returned value). The refcount lets
|
||||
* el_list_append and el_map_set mutate in place when uniquely owned (cheap)
|
||||
* and copy-on-write when shared (preserves persistent semantics across
|
||||
* accumulator patterns in the compiler itself). */
|
||||
|
||||
void el_retain(el_val_t v);
|
||||
void el_release(el_val_t v);
|
||||
|
||||
/* ── Arena scoping ────────────────────────────────────────────────────────────
|
||||
* el_arena_push() activates the string arena (if not already active) and
|
||||
* returns a mark; el_arena_pop(mark) frees all strings allocated since that
|
||||
* mark. Used by codegen for per-function/statement scoping and by long-running
|
||||
* EL loops (e.g. the soul daemon's awareness tick) to reclaim per-iteration
|
||||
* allocations. */
|
||||
el_val_t el_arena_push(void);
|
||||
el_val_t el_arena_pop(el_val_t mark);
|
||||
|
||||
/* ── List ────────────────────────────────────────────────────────────────── */
|
||||
|
||||
el_val_t el_list_new(el_val_t count, ...);
|
||||
el_val_t el_list_len(el_val_t list);
|
||||
el_val_t el_list_get(el_val_t list, el_val_t index);
|
||||
el_val_t el_list_append(el_val_t list, el_val_t elem);
|
||||
el_val_t el_list_empty(void);
|
||||
el_val_t el_list_clone(el_val_t list);
|
||||
|
||||
/* ── Map ─────────────────────────────────────────────────────────────────── */
|
||||
|
||||
el_val_t el_map_new(el_val_t pair_count, ...);
|
||||
el_val_t el_get_field(el_val_t map, el_val_t key);
|
||||
el_val_t el_map_get(el_val_t map, el_val_t key);
|
||||
el_val_t el_map_set(el_val_t map, el_val_t key, el_val_t value);
|
||||
|
||||
/* ── HTTP ─────────────────────────────────────────────────────────────────── */
|
||||
|
||||
el_val_t http_get(el_val_t url);
|
||||
el_val_t http_post(el_val_t url, el_val_t body);
|
||||
el_val_t http_post_json(el_val_t url, el_val_t json_body);
|
||||
el_val_t http_get_with_headers(el_val_t url, el_val_t headers_map);
|
||||
el_val_t http_post_with_headers(el_val_t url, el_val_t body, el_val_t headers_map);
|
||||
el_val_t http_post_form_auth(el_val_t url, el_val_t form_body, el_val_t auth_header);
|
||||
el_val_t http_delete(el_val_t url);
|
||||
el_val_t http_delete_json(el_val_t url, el_val_t json_body);
|
||||
void http_serve(el_val_t port, el_val_t handler);
|
||||
void http_set_handler(el_val_t name);
|
||||
|
||||
/* HTTP server v2 ─────────────────────────────────────────────────────────────
|
||||
* Same dispatch model as http_serve, but the handler signature is widened:
|
||||
*
|
||||
* el_val_t handler(method, path, headers_map, body)
|
||||
*
|
||||
* `headers_map` is an ElMap from lowercased header name → header value (both
|
||||
* Strings). Repeated headers are joined with ", " per RFC 7230.
|
||||
*
|
||||
* Response value: the handler may return either
|
||||
* (a) a plain body string — same auto-content-type / 200-OK behaviour as
|
||||
* http_serve (3-arg) — or
|
||||
* (b) a response envelope built with `http_response(status, headers_json,
|
||||
* body)`. The runtime detects the envelope discriminator
|
||||
* `"el_http_response":1` at the start of the returned string and
|
||||
* unpacks status / headers / body before sending.
|
||||
*
|
||||
* The 3-arg http_serve(port, handler) remains supported unchanged for
|
||||
* existing handlers (e.g. products/web/server.el): it dispatches with
|
||||
* (method, path, body), hardcodes 200 OK, and auto-detects content type. */
|
||||
void http_serve_v2(el_val_t port, el_val_t handler);
|
||||
void http_set_handler_v2(el_val_t name);
|
||||
|
||||
/* Non-blocking variant of http_serve: runs the accept loop in a background
|
||||
* pthread and returns immediately so the caller can continue (used by the
|
||||
* soul daemon to run awareness_run() after starting its HTTP API). */
|
||||
void http_serve_async(el_val_t port, el_val_t handler);
|
||||
|
||||
/* Build an HTTP response envelope. `headers_json` should be a JSON object
|
||||
* literal like `{"WWW-Authenticate":"Basic"}` (or "" / "{}" for none). The
|
||||
* returned string carries the discriminator `{"el_http_response":1,...}`
|
||||
* which the runtime's send-path detects and unpacks. Detection happens
|
||||
* uniformly inside http_send_response, so a 3-arg handler may also return
|
||||
* an envelope. The 3-arg variant remains documented as a fixed 200-OK
|
||||
* auto-content-type contract for legacy handlers that return plain bodies. */
|
||||
el_val_t http_response(el_val_t status, el_val_t headers_json, el_val_t body);
|
||||
|
||||
/* HTTP timeout — every libcurl request honors EL_HTTP_TIMEOUT_MS (default
|
||||
* 60000ms). Read lazily on first use, so setting the env var any time before
|
||||
* the first http_* call is sufficient. */
|
||||
|
||||
/* Streaming variants — write the response body straight to a file via
|
||||
* libcurl's CURLOPT_WRITEFUNCTION = fwrite. These bypass the el_val_t string
|
||||
* wrapper entirely, so binary payloads (audio/mpeg, image/png, etc.) survive
|
||||
* embedded NUL bytes that would truncate a strlen()-based code path.
|
||||
*
|
||||
* Both honor EL_HTTP_TIMEOUT_MS, follow redirects, and accept the same
|
||||
* `headers_map` shape as http_post_with_headers (ElMap of String→String).
|
||||
*
|
||||
* Return value: 1 on success (file fully written), 0 on any failure
|
||||
* (network, file open, partial write). On failure the output file is removed
|
||||
* so callers cannot mistake a partially-written file for a valid one. */
|
||||
el_val_t http_post_to_file(el_val_t url, el_val_t body, el_val_t headers_map, el_val_t output_path);
|
||||
el_val_t http_get_to_file(el_val_t url, el_val_t headers_map, el_val_t output_path);
|
||||
|
||||
/* ── URL encoding ────────────────────────────────────────────────────────── */
|
||||
|
||||
el_val_t url_encode(el_val_t s); /* RFC 3986 unreserved set */
|
||||
el_val_t url_decode(el_val_t s); /* '+' → space, %XX → byte */
|
||||
|
||||
/* ── HTML allowlist sanitizer ────────────────────────────────────────────────
|
||||
* el_html_sanitize(input_html, allowlist_json) — strict allowlist HTML
|
||||
* cleaner. State-machine parser; tag/attribute names compared case-
|
||||
* insensitively against the allowlist; `<a href>` / `<… src>` URL schemes
|
||||
* validated (http, https, mailto, fragment-only, or relative); whole-
|
||||
* subtree drop for script / style / iframe / object / embed / form; HTML-
|
||||
* escapes free text outside dropped subtrees.
|
||||
*
|
||||
* The allowlist is JSON of the form
|
||||
* {"p":[],"a":["href","title"],"strong":[],...}
|
||||
* where each value is the array of attribute names allowed for that tag. */
|
||||
el_val_t el_html_sanitize(el_val_t input_html, el_val_t allowlist_json);
|
||||
|
||||
/* ── Filesystem ──────────────────────────────────────────────────────────── */
|
||||
|
||||
el_val_t fs_read(el_val_t path);
|
||||
el_val_t fs_write(el_val_t path, el_val_t content);
|
||||
el_val_t fs_list(el_val_t path);
|
||||
el_val_t fs_exists(el_val_t path);
|
||||
el_val_t fs_mkdir(el_val_t path); /* mkdir -p, mode 0755 */
|
||||
|
||||
/* Length-explicit binary write. `length` is an Int (el_val_t holding the
|
||||
* byte count). The caller knows the length from context — typically because
|
||||
* `bytes` came from base64_decode (which produces a magic-tagged binary
|
||||
* buffer with embedded NULs possible) and the caller already tracks the
|
||||
* decoded length, OR because the bytes came from a fixed-size source
|
||||
* (sha256_bytes = 32, hmac_sha256_bytes = 32). Bypasses strlen entirely.
|
||||
*
|
||||
* Returns 1 on success, 0 on failure (invalid path, can't open, partial
|
||||
* write, negative length). On partial-write failure, the file is removed
|
||||
* so callers cannot read back a truncated artefact. */
|
||||
el_val_t fs_write_bytes(el_val_t path, el_val_t bytes, el_val_t length);
|
||||
|
||||
/* ── JSON ────────────────────────────────────────────────────────────────── */
|
||||
|
||||
el_val_t json_get(el_val_t json, el_val_t key);
|
||||
el_val_t json_parse(el_val_t s);
|
||||
el_val_t json_stringify(el_val_t v);
|
||||
el_val_t json_get_string(el_val_t json_str, el_val_t key);
|
||||
el_val_t json_get_int(el_val_t json_str, el_val_t key);
|
||||
el_val_t json_get_float(el_val_t json_str, el_val_t key);
|
||||
el_val_t json_get_bool(el_val_t json_str, el_val_t key);
|
||||
el_val_t json_get_raw(el_val_t json_str, el_val_t key);
|
||||
el_val_t json_set(el_val_t json_str, el_val_t key, el_val_t value);
|
||||
el_val_t json_array_len(el_val_t json_str);
|
||||
el_val_t json_array_get(el_val_t json_str, el_val_t index);
|
||||
el_val_t json_array_get_string(el_val_t json_str, el_val_t index);
|
||||
|
||||
/* ── Time ────────────────────────────────────────────────────────────────── */
|
||||
|
||||
el_val_t time_now(void);
|
||||
el_val_t time_now_utc(void);
|
||||
el_val_t sleep_secs(el_val_t secs);
|
||||
el_val_t sleep_ms(el_val_t ms);
|
||||
el_val_t time_format(el_val_t ts, el_val_t fmt);
|
||||
el_val_t time_to_parts(el_val_t ts);
|
||||
el_val_t time_from_parts(el_val_t secs, el_val_t ns, el_val_t tz);
|
||||
el_val_t time_add(el_val_t ts, el_val_t n, el_val_t unit);
|
||||
el_val_t time_diff(el_val_t ts1, el_val_t ts2, el_val_t unit);
|
||||
|
||||
/* ── Instant + Duration: first-class temporal types ──────────────────────────
|
||||
* Both types share the el_val_t (int64) slot. Instants are nanoseconds
|
||||
* since the Unix epoch; Durations are signed nanoseconds. Type discipline
|
||||
* is enforced at codegen-time: BinOps on names registered as Instant or
|
||||
* Duration route through the typed wrappers below; mismatches like
|
||||
* Instant+Instant become #error at the C compiler.
|
||||
*
|
||||
* Postfix literals — `30.seconds`, `1.hour`, `500.millis`, `30.nanos` — are
|
||||
* recognised by the parser as DurationLit AST nodes and lowered to literal
|
||||
* int64 nanoseconds at codegen time. The runtime never sees the units. */
|
||||
|
||||
el_val_t el_now_instant(void);
|
||||
el_val_t now(void);
|
||||
el_val_t unix_seconds(el_val_t n);
|
||||
el_val_t unix_millis(el_val_t n);
|
||||
el_val_t instant_from_iso8601(el_val_t s);
|
||||
|
||||
el_val_t el_duration_from_nanos(el_val_t ns);
|
||||
el_val_t duration_seconds(el_val_t n);
|
||||
el_val_t duration_millis(el_val_t n);
|
||||
el_val_t duration_nanos(el_val_t n);
|
||||
|
||||
el_val_t el_instant_add_dur(el_val_t inst, el_val_t dur);
|
||||
el_val_t el_instant_sub_dur(el_val_t inst, el_val_t dur);
|
||||
el_val_t el_instant_diff(el_val_t a, el_val_t b);
|
||||
el_val_t el_duration_add(el_val_t a, el_val_t b);
|
||||
el_val_t el_duration_sub(el_val_t a, el_val_t b);
|
||||
el_val_t el_duration_scale(el_val_t dur, el_val_t scalar);
|
||||
el_val_t el_duration_div(el_val_t dur, el_val_t scalar);
|
||||
|
||||
el_val_t el_instant_lt(el_val_t a, el_val_t b);
|
||||
el_val_t el_instant_le(el_val_t a, el_val_t b);
|
||||
el_val_t el_instant_gt(el_val_t a, el_val_t b);
|
||||
el_val_t el_instant_ge(el_val_t a, el_val_t b);
|
||||
el_val_t el_instant_eq(el_val_t a, el_val_t b);
|
||||
el_val_t el_instant_ne(el_val_t a, el_val_t b);
|
||||
el_val_t el_duration_lt(el_val_t a, el_val_t b);
|
||||
el_val_t el_duration_le(el_val_t a, el_val_t b);
|
||||
el_val_t el_duration_gt(el_val_t a, el_val_t b);
|
||||
el_val_t el_duration_ge(el_val_t a, el_val_t b);
|
||||
el_val_t el_duration_eq(el_val_t a, el_val_t b);
|
||||
el_val_t el_duration_ne(el_val_t a, el_val_t b);
|
||||
|
||||
el_val_t instant_to_unix_seconds(el_val_t i);
|
||||
el_val_t instant_to_unix_millis(el_val_t i);
|
||||
el_val_t instant_to_iso8601(el_val_t i);
|
||||
el_val_t duration_to_seconds(el_val_t d);
|
||||
el_val_t duration_to_millis(el_val_t d);
|
||||
el_val_t duration_to_nanos(el_val_t d);
|
||||
|
||||
el_val_t el_sleep_duration(el_val_t dur);
|
||||
el_val_t unix_timestamp(void);
|
||||
|
||||
el_val_t ttl_cache_set(el_val_t key, el_val_t value);
|
||||
el_val_t ttl_cache_get(el_val_t key, el_val_t max_age);
|
||||
el_val_t ttl_cache_age(el_val_t key);
|
||||
|
||||
/* ── Calendar + CalendarTime + Rhythm + LocalDate/Time/DateTime ─────────────
|
||||
* Phase 1.5 of the time system. Calendar is pluggable: EarthCalendar (IANA
|
||||
* zones, Gregorian, DST) is the user-facing default; MarsCalendar,
|
||||
* CycleCalendar(period), NoCycleCalendar, RelativeCalendar handle non-Earth
|
||||
* domains.
|
||||
*
|
||||
* A Calendar interprets an Instant under a particular cycle convention and
|
||||
* produces a CalendarTime. CalendarTime carries the underlying Instant and
|
||||
* a back-pointer to its Calendar; arithmetic and formatting consult the
|
||||
* Calendar to convert ns since epoch into year/month/day/hour/minute/second
|
||||
* (or sol/phase, or cycle/phase, depending on kind).
|
||||
*
|
||||
* Storage convention: Calendar / CalendarTime / Rhythm / LocalDate /
|
||||
* LocalDateTime are heap-allocated structs whose pointers are cast into
|
||||
* el_val_t. A 24-bit magic header at offset 0 lets the runtime identify
|
||||
* the kind safely. LocalTime is small enough to live in the int64 slot
|
||||
* directly (nanos since midnight, signed). */
|
||||
|
||||
/* Zone — opaque IANA zone or fixed offset, used by EarthCalendar.
|
||||
* `zone_id` is either an IANA name ("America/New_York", "UTC") or a fixed
|
||||
* offset string ("+05:30", "-08:00"). The runtime resolves it via tzset()
|
||||
* on first use of the owning EarthCalendar. */
|
||||
el_val_t zone(el_val_t id);
|
||||
el_val_t zone_utc(void);
|
||||
el_val_t zone_local(void);
|
||||
el_val_t zone_offset(el_val_t hours, el_val_t minutes);
|
||||
|
||||
/* Calendar constructors. Each returns an el_val_t pointer to a heap-
|
||||
* allocated, magic-tagged Calendar struct. Calendars are interned by
|
||||
* (kind, zone_id, period_ns, epoch_ns) so identical constructors return
|
||||
* the same pointer — equality is reference equality. */
|
||||
el_val_t earth_calendar(el_val_t z);
|
||||
el_val_t earth_calendar_default(void);
|
||||
el_val_t mars_calendar(void);
|
||||
el_val_t cycle_calendar(el_val_t period_dur);
|
||||
el_val_t no_cycle_calendar(void);
|
||||
el_val_t relative_calendar(el_val_t epoch_inst);
|
||||
|
||||
/* CalendarTime constructors and methods. Returns a heap-allocated struct
|
||||
* whose pointer fits in el_val_t. */
|
||||
el_val_t now_in(el_val_t cal);
|
||||
el_val_t in_calendar(el_val_t inst, el_val_t cal);
|
||||
el_val_t cal_format(el_val_t ct, el_val_t pattern);
|
||||
el_val_t cal_to_instant(el_val_t ct);
|
||||
el_val_t cal_cycle_phase(el_val_t ct);
|
||||
el_val_t cal_in(el_val_t ct, el_val_t cal);
|
||||
|
||||
/* LocalDate / LocalTime / LocalDateTime — calendar-agnostic value types.
|
||||
* LocalTime carries nanoseconds since midnight as a signed int64 directly
|
||||
* in the el_val_t slot (no allocation). LocalDate / LocalDateTime are
|
||||
* heap-allocated structs with magic headers. */
|
||||
el_val_t local_date(el_val_t y, el_val_t m, el_val_t d);
|
||||
el_val_t local_time(el_val_t h, el_val_t m, el_val_t s, el_val_t ns);
|
||||
el_val_t local_datetime(el_val_t date, el_val_t time);
|
||||
el_val_t zoned(el_val_t date, el_val_t time, el_val_t cal);
|
||||
|
||||
el_val_t local_date_year(el_val_t ld);
|
||||
el_val_t local_date_month(el_val_t ld);
|
||||
el_val_t local_date_day(el_val_t ld);
|
||||
el_val_t local_time_hour(el_val_t lt);
|
||||
el_val_t local_time_minute(el_val_t lt);
|
||||
el_val_t local_time_second(el_val_t lt);
|
||||
el_val_t local_time_nanos(el_val_t lt);
|
||||
|
||||
el_val_t el_local_date_add_dur(el_val_t ld, el_val_t dur);
|
||||
el_val_t el_local_time_add_dur(el_val_t lt, el_val_t dur);
|
||||
el_val_t el_local_date_lt(el_val_t a, el_val_t b);
|
||||
el_val_t el_local_date_eq(el_val_t a, el_val_t b);
|
||||
|
||||
/* Rhythm — pluggable recurrence AST. Returns a heap-allocated struct
|
||||
* pointer in el_val_t; rhythms are immutable so callers may share them. */
|
||||
el_val_t rhythm_cycle_start(void);
|
||||
el_val_t rhythm_cycle_phase(el_val_t phase);
|
||||
el_val_t rhythm_duration(el_val_t d);
|
||||
el_val_t rhythm_session_start(void);
|
||||
el_val_t rhythm_event(el_val_t name);
|
||||
el_val_t rhythm_and(el_val_t a, el_val_t b);
|
||||
el_val_t rhythm_or(el_val_t a, el_val_t b);
|
||||
el_val_t rhythm_weekday(el_val_t day);
|
||||
el_val_t rhythm_weekly_at(el_val_t day, el_val_t hour, el_val_t minute);
|
||||
el_val_t rhythm_next_after(el_val_t r, el_val_t after, el_val_t cal);
|
||||
el_val_t rhythm_matches(el_val_t r, el_val_t ct);
|
||||
|
||||
/* ── UUID ────────────────────────────────────────────────────────────────── */
|
||||
|
||||
el_val_t uuid_new(void);
|
||||
el_val_t uuid_v4(void);
|
||||
|
||||
/* ── Environment ─────────────────────────────────────────────────────────── */
|
||||
|
||||
el_val_t env(el_val_t key);
|
||||
|
||||
/* ── In-process state K/V ────────────────────────────────────────────────── */
|
||||
|
||||
el_val_t state_set(el_val_t key, el_val_t value);
|
||||
el_val_t state_get(el_val_t key);
|
||||
el_val_t state_del(el_val_t key);
|
||||
el_val_t state_keys(void);
|
||||
|
||||
/* ── Float formatting ────────────────────────────────────────────────────── */
|
||||
|
||||
el_val_t float_to_str(el_val_t f);
|
||||
el_val_t int_to_float(el_val_t n);
|
||||
el_val_t float_to_int(el_val_t f);
|
||||
el_val_t format_float(el_val_t f, el_val_t decimals);
|
||||
el_val_t decimal_round(el_val_t f, el_val_t decimals);
|
||||
el_val_t str_to_float(el_val_t s);
|
||||
|
||||
/* ── Math (Float-aware) ──────────────────────────────────────────────────── */
|
||||
|
||||
el_val_t math_sqrt(el_val_t f);
|
||||
el_val_t math_log(el_val_t f);
|
||||
el_val_t math_ln(el_val_t f);
|
||||
el_val_t math_sin(el_val_t f);
|
||||
el_val_t math_cos(el_val_t f);
|
||||
el_val_t math_pi(void);
|
||||
|
||||
/* ── String additions ────────────────────────────────────────────────────── */
|
||||
|
||||
el_val_t str_index_of(el_val_t s, el_val_t sub);
|
||||
el_val_t str_split(el_val_t s, el_val_t sep);
|
||||
el_val_t str_char_at(el_val_t s, el_val_t i);
|
||||
el_val_t str_char_code(el_val_t s, el_val_t i);
|
||||
el_val_t str_pad_left(el_val_t s, el_val_t width, el_val_t pad);
|
||||
el_val_t str_pad_right(el_val_t s, el_val_t width, el_val_t pad);
|
||||
el_val_t str_format(el_val_t fmt, el_val_t data);
|
||||
el_val_t str_lower(el_val_t s);
|
||||
el_val_t str_upper(el_val_t s);
|
||||
|
||||
/* ── Text-processing primitives (Phase 1: byte/codepoint, ASCII char classes)
|
||||
* Phase 2 (filed): Unicode-grapheme awareness, NFC/NFD normalization, regex.
|
||||
* is_* predicates: empty input returns false; multi-char requires ALL bytes
|
||||
* to match. ASCII ranges only in Phase 1. */
|
||||
|
||||
/* Counting */
|
||||
el_val_t str_count(el_val_t s, el_val_t sub); /* non-overlapping */
|
||||
el_val_t str_count_chars(el_val_t s); /* codepoint count */
|
||||
el_val_t str_count_bytes(el_val_t s); /* alias of str_len */
|
||||
el_val_t str_count_lines(el_val_t s);
|
||||
el_val_t str_count_words(el_val_t s);
|
||||
el_val_t str_count_letters(el_val_t s); /* ASCII [A-Za-z] */
|
||||
el_val_t str_count_digits(el_val_t s); /* ASCII [0-9] */
|
||||
|
||||
/* Find / position */
|
||||
el_val_t str_index_of_all(el_val_t s, el_val_t sub); /* [Int] of byte offsets */
|
||||
el_val_t str_last_index_of(el_val_t s, el_val_t sub);
|
||||
el_val_t str_find_chars(el_val_t s, el_val_t any_of); /* first idx of any ch */
|
||||
|
||||
/* Transform */
|
||||
el_val_t str_repeat(el_val_t s, el_val_t n);
|
||||
el_val_t str_reverse(el_val_t s); /* by codepoint */
|
||||
el_val_t str_strip_prefix(el_val_t s, el_val_t prefix);
|
||||
el_val_t str_strip_suffix(el_val_t s, el_val_t suffix);
|
||||
el_val_t str_strip_chars(el_val_t s, el_val_t chars);
|
||||
el_val_t str_lstrip(el_val_t s);
|
||||
el_val_t str_rstrip(el_val_t s);
|
||||
|
||||
/* Char classification (Bool) */
|
||||
el_val_t is_letter(el_val_t s);
|
||||
el_val_t is_digit(el_val_t s);
|
||||
el_val_t is_alphanumeric(el_val_t s);
|
||||
el_val_t is_whitespace(el_val_t s);
|
||||
el_val_t is_punctuation(el_val_t s);
|
||||
el_val_t is_uppercase(el_val_t s);
|
||||
el_val_t is_lowercase(el_val_t s);
|
||||
|
||||
/* Split / join */
|
||||
el_val_t str_split_lines(el_val_t s);
|
||||
el_val_t str_split_chars(el_val_t s); /* alias of native_string_chars */
|
||||
el_val_t str_split_n(el_val_t s, el_val_t sep, el_val_t n);
|
||||
el_val_t str_join(el_val_t list, el_val_t sep); /* alias of list_join */
|
||||
|
||||
/* ── List additions ──────────────────────────────────────────────────────── */
|
||||
|
||||
el_val_t list_push(el_val_t list, el_val_t elem);
|
||||
el_val_t list_push_front(el_val_t list, el_val_t elem);
|
||||
el_val_t list_join(el_val_t list, el_val_t sep);
|
||||
el_val_t list_range(el_val_t start, el_val_t end);
|
||||
|
||||
/* ── Bool helpers ────────────────────────────────────────────────────────── */
|
||||
|
||||
el_val_t bool_to_str(el_val_t b);
|
||||
|
||||
/* ── Numeric parsing ─────────────────────────────────────────────────────── */
|
||||
|
||||
el_val_t parse_int(el_val_t s, el_val_t default_val);
|
||||
|
||||
/* ── Process ─────────────────────────────────────────────────────────────── */
|
||||
|
||||
void exit_program(el_val_t code);
|
||||
el_val_t getpid_now(void);
|
||||
|
||||
/* ── CGI identity ─────────────────────────────────────────────────────────────
|
||||
* Called at the start of main() in CGI programs (those with a `cgi {}` block).
|
||||
* Records the program's DHARMA identity before any other code executes. */
|
||||
|
||||
void el_cgi_init(el_val_t name, el_val_t dharma_id, el_val_t principal,
|
||||
el_val_t network, el_val_t engram);
|
||||
|
||||
/* ── DHARMA network builtins ─────────────────────────────────────────────────
|
||||
* Available to CGI programs (declared with a `cgi {}` block).
|
||||
*
|
||||
* Peers are addressed by `dharma_id` of the form
|
||||
* "<registry-id>@<transport-url>" e.g. "ntn-genesis@http://localhost:7770"
|
||||
* If the @<url> portion is omitted, transport defaults to
|
||||
* "http://localhost:7770" (the local CGI daemon assumption).
|
||||
*
|
||||
* Wire protocol (all peers expose):
|
||||
* POST <url>/dharma/recv { channel, from, content } → response body
|
||||
* POST <url>/dharma/event { type, payload, source, timestamp }
|
||||
* POST <url>/api/activate { query } → list of nodes
|
||||
*
|
||||
* Hosting application's responsibility: an El program with a `cgi {}` block
|
||||
* runs http_serve() with its own request handler; that handler should route
|
||||
* "/dharma/event" requests by calling el_runtime_dharma_event_arrive() so
|
||||
* incoming events feed dharma_field() queues. The runtime itself does not
|
||||
* intercept any /dharma path. */
|
||||
|
||||
el_val_t dharma_connect(el_val_t cgi_id);
|
||||
el_val_t dharma_send(el_val_t channel, el_val_t content);
|
||||
el_val_t dharma_activate(el_val_t query);
|
||||
void dharma_emit(el_val_t event_type, el_val_t payload);
|
||||
el_val_t dharma_field(el_val_t event_type);
|
||||
void dharma_strengthen(el_val_t cgi_id, el_val_t weight);
|
||||
el_val_t dharma_relationship(el_val_t cgi_id);
|
||||
el_val_t dharma_peers(void);
|
||||
|
||||
/* Public C API: called by an El program's HTTP handler when a /dharma/event
|
||||
* request arrives. Pushes onto the per-event-type queue and signals any
|
||||
* pending dharma_field() blockers. All three arguments must be NUL-terminated
|
||||
* C strings (or NULL — then treated as empty). */
|
||||
void el_runtime_dharma_event_arrive(const char* event_type,
|
||||
const char* payload,
|
||||
const char* source);
|
||||
|
||||
/* ── Engram local graph primitives ───────────────────────────────────────────
|
||||
* Operate on the CGI's local Engram knowledge graph.
|
||||
* `engram_activate` queries the local graph only; `dharma_activate` is
|
||||
* network-wide across all connected CGI graphs. */
|
||||
|
||||
el_val_t engram_node(el_val_t content, el_val_t node_type, el_val_t salience);
|
||||
el_val_t engram_node_full(el_val_t content, el_val_t node_type, el_val_t label,
|
||||
el_val_t salience, el_val_t importance, el_val_t confidence,
|
||||
el_val_t tier, el_val_t tags);
|
||||
/* Layered consciousness — see el_runtime.c for the layered architecture
|
||||
* design notes (search "Layered consciousness architecture"). The five
|
||||
* canonical layers (safety / core-identity / domain-knowledge / imprint /
|
||||
* suit) are seeded automatically; engram_add_layer extends the registry
|
||||
* with imprint or suit overlays at runtime. Nodes default to layer 1
|
||||
* (core-identity) when created via engram_node / engram_node_full. */
|
||||
el_val_t engram_node_layered(el_val_t content, el_val_t node_type, el_val_t label,
|
||||
el_val_t salience, el_val_t certainty, el_val_t confidence,
|
||||
el_val_t status, el_val_t tags, el_val_t layer_id);
|
||||
el_val_t engram_add_layer(el_val_t name, el_val_t priority, el_val_t suppressible,
|
||||
el_val_t transparent, el_val_t injectable);
|
||||
el_val_t engram_remove_layer(el_val_t layer_id);
|
||||
el_val_t engram_list_layers(void);
|
||||
el_val_t engram_get_node(el_val_t id);
|
||||
void engram_strengthen(el_val_t node_id);
|
||||
void engram_forget(el_val_t node_id);
|
||||
el_val_t engram_prune_telemetry(el_val_t older_than_ms);
|
||||
el_val_t engram_node_count(void);
|
||||
el_val_t engram_search(el_val_t query, el_val_t limit);
|
||||
el_val_t engram_scan_nodes(el_val_t limit, el_val_t offset);
|
||||
void engram_connect(el_val_t from_id, el_val_t to_id, el_val_t weight, el_val_t relation);
|
||||
el_val_t engram_edge_between(el_val_t from_id, el_val_t to_id);
|
||||
el_val_t engram_neighbors(el_val_t node_id);
|
||||
el_val_t engram_neighbors_filtered(el_val_t node_id, el_val_t max_depth, el_val_t direction);
|
||||
el_val_t engram_edge_count(void);
|
||||
/* Three-pass activation: background fan-out → working-memory promotion →
|
||||
* Layer 0 override. See "Three-pass activation" in el_runtime.c. */
|
||||
el_val_t engram_activate(el_val_t query, el_val_t depth);
|
||||
el_val_t engram_save(el_val_t path);
|
||||
el_val_t engram_load(el_val_t path);
|
||||
|
||||
/* JSON-string accessors — return pre-serialized JSON so HTTP handlers
|
||||
* can pass results straight through without round-tripping ElList/ElMap
|
||||
* through json_stringify. */
|
||||
el_val_t engram_get_node_json(el_val_t id);
|
||||
el_val_t engram_get_node_by_label(el_val_t label);
|
||||
el_val_t engram_search_json(el_val_t query, el_val_t limit);
|
||||
el_val_t engram_scan_nodes_json(el_val_t limit, el_val_t offset);
|
||||
el_val_t engram_scan_nodes_by_type_json(el_val_t node_type, el_val_t limit, el_val_t offset);
|
||||
el_val_t engram_neighbors_json(el_val_t node_id, el_val_t max_depth, el_val_t direction);
|
||||
el_val_t engram_activate_json(el_val_t query, el_val_t depth);
|
||||
el_val_t engram_stats_json(void);
|
||||
el_val_t engram_act_stats_json(void);
|
||||
el_val_t engram_cosine_sim(el_val_t id_a, el_val_t id_b);
|
||||
/* Document frequency of a term across node labels — term-specificity signal
|
||||
* for curiosity seed selection. (2026-08-03 self-review.) */
|
||||
el_val_t engram_label_df(el_val_t term);
|
||||
el_val_t engram_embed_backfill(el_val_t count);
|
||||
el_val_t engram_list_layers_json(void);
|
||||
/* Working memory introspection — count, mean weight, and top-N snapshot.
|
||||
* Ported from el-compiler/runtime on 2026-06-30 self-review. */
|
||||
el_val_t engram_wm_count(void);
|
||||
el_val_t engram_wm_avg_weight(void);
|
||||
el_val_t engram_wm_top_json(el_val_t n);
|
||||
/* Merge-load: add nodes/edges from a snapshot without resetting the store. */
|
||||
el_val_t engram_load_merge(el_val_t path);
|
||||
/* engram_compile_layered_json — produce a prompt-ready text block split
|
||||
* into "[LAYER 0 — STRUCTURAL]" (non-suppressible layers, sacred fire)
|
||||
* and "[ENGRAM CONTEXT]" (standard suppressible layers). Returns "" if
|
||||
* no nodes promoted to working memory. */
|
||||
el_val_t engram_compile_layered_json(el_val_t intent, el_val_t depth);
|
||||
|
||||
/* ── LLM (Anthropic API client) ─────────────────────────────────────────────
|
||||
* All functions call https://api.anthropic.com/v1/messages with the API key
|
||||
* from env ANTHROPIC_API_KEY. Default model when empty: claude-sonnet-4-5. */
|
||||
|
||||
el_val_t llm_call(el_val_t model, el_val_t prompt);
|
||||
el_val_t llm_call_system(el_val_t model, el_val_t system_prompt, el_val_t user_prompt);
|
||||
el_val_t llm_call_agentic(el_val_t model, el_val_t system, el_val_t user, el_val_t tools);
|
||||
el_val_t llm_vision(el_val_t model, el_val_t system, el_val_t prompt, el_val_t image_url_or_b64);
|
||||
el_val_t llm_models(void);
|
||||
|
||||
/* Register a tool handler by name. The handler is looked up via dlsym
|
||||
* (mirroring http_set_handler), so any El `fn <name>(input)` compiles to
|
||||
* a global C symbol that this function can locate at runtime.
|
||||
* Handler signature: `el_val_t handler(el_val_t input_json)` — receives
|
||||
* the tool input as a JSON-string el_val_t and returns a JSON-string
|
||||
* el_val_t result. Used by llm_call_agentic. */
|
||||
void llm_register_tool(el_val_t name, el_val_t handler_fn_name);
|
||||
|
||||
/* ── args() ─────────────────────────────────────────────────────────────────
|
||||
* Provides access to command-line arguments passed to the program.
|
||||
* Populated by el_runtime_init_args() before main() runs. */
|
||||
|
||||
el_val_t args(void);
|
||||
void el_runtime_init_args(int argc, char** argv);
|
||||
|
||||
/* ── Crypto primitives ─────────────────────────────────────────────────────
|
||||
* SHA-256, HMAC-SHA-256, and base64 (standard + URL-safe).
|
||||
* Self-contained — no OpenSSL/libcrypto dependency. The implementations are
|
||||
* adapted from public-domain reference code (Brad Conte / RFC 4648).
|
||||
*
|
||||
* Bytes-returning variants (sha256_bytes, hmac_sha256_bytes) return a string
|
||||
* value whose contents are raw binary; callers usually feed these into
|
||||
* base64_encode. Note that el_val_t strings are NUL-terminated by convention,
|
||||
* so the binary payload may contain embedded NULs — pass it directly into
|
||||
* base64_encode (which uses an explicit length) rather than treating it as
|
||||
* a printable C string.
|
||||
*
|
||||
* The "base64" variants emit/accept RFC 4648 standard alphabet with padding.
|
||||
* The "base64url" variants use URL-safe alphabet (`-`/`_`) with no padding,
|
||||
* as used in JWTs. */
|
||||
|
||||
el_val_t sha256_hex(el_val_t input);
|
||||
el_val_t sha256_bytes(el_val_t input);
|
||||
el_val_t hmac_sha256_hex(el_val_t key, el_val_t message);
|
||||
el_val_t hmac_sha256_bytes(el_val_t key, el_val_t message);
|
||||
el_val_t base64_encode(el_val_t input);
|
||||
el_val_t base64_decode(el_val_t input);
|
||||
el_val_t base64url_encode(el_val_t input);
|
||||
el_val_t base64url_decode(el_val_t input);
|
||||
|
||||
/* Length-aware variants (internal — exposed for the rare caller that already
|
||||
* has a known-length binary buffer and doesn't want to round-trip through
|
||||
* a NUL-terminated el_val_t string). Sha256_bytes and hmac_sha256_bytes feed
|
||||
* these implicitly. */
|
||||
el_val_t el_sha256_bytes_n(const unsigned char* data, size_t len);
|
||||
el_val_t el_base64_encode_n(const unsigned char* data, size_t len, int url_safe);
|
||||
|
||||
/* ── Post-quantum primitives (liboqs-backed) ────────────────────────────────
|
||||
* All inputs/outputs hex-encoded. Algorithm choices:
|
||||
* Signature: CRYSTALS-Dilithium-3 (NIST level 3, balanced)
|
||||
* KEM: CRYSTALS-Kyber-768 (NIST level 3)
|
||||
* Hash: SHA3-256 (Keccak) (PQ-aware protocols favour SHA3 over SHA2)
|
||||
*
|
||||
* If liboqs is not linked (detected via __has_include(<oqs/oqs.h>) at compile
|
||||
* time), the pq_* entry points return a JSON-shaped error string so callers
|
||||
* fail loudly rather than silently fall back to classical schemes:
|
||||
* {"error":"liboqs not linked, post-quantum primitives unavailable"}
|
||||
*
|
||||
* The hybrid handshake pairs X25519 with Kyber-768 per NIST PQ guidance and
|
||||
* CNSA 2.0. Combined shared secret is HKDF-SHA256(x25519_ss || kyber_ss).
|
||||
* Even if Kyber falls, X25519 holds; if X25519 falls under quantum attack,
|
||||
* Kyber holds. SHA3-256 also remains usable independent of liboqs (the
|
||||
* Keccak permutation is PQ-OK as a primitive). */
|
||||
|
||||
el_val_t pq_keygen_signature(void);
|
||||
el_val_t pq_sign(el_val_t secret_key_hex, el_val_t message);
|
||||
el_val_t pq_verify(el_val_t public_key_hex, el_val_t message, el_val_t signature_hex);
|
||||
|
||||
el_val_t pq_kem_keygen(void);
|
||||
el_val_t pq_kem_encaps(el_val_t public_key_hex);
|
||||
el_val_t pq_kem_decaps(el_val_t secret_key_hex, el_val_t ciphertext_hex);
|
||||
|
||||
el_val_t pq_hybrid_keygen(void);
|
||||
el_val_t pq_hybrid_handshake(el_val_t remote_pub_combined);
|
||||
|
||||
el_val_t sha3_256_hex(el_val_t input);
|
||||
|
||||
/* ── AEAD: AES-256-GCM (libcrypto-backed) ───────────────────────────────────
|
||||
* Symmetric authenticated encryption used to wrap envelopes after a KEM
|
||||
* handshake. Caller MUST supply a 32-byte key (64 hex chars) — typically the
|
||||
* Kyber-768 / hybrid shared_secret, optionally normalized via SHA3-256.
|
||||
*
|
||||
* aead_encrypt returns a JSON map {"nonce":"...","ciphertext":"..."} where
|
||||
* ciphertext is the AES-256-GCM output with the 16-byte auth tag appended.
|
||||
* Nonce is a fresh 12-byte CSPRNG draw — callers never pick the nonce, which
|
||||
* structurally rules out the GCM nonce-reuse footgun.
|
||||
*
|
||||
* aead_decrypt returns the plaintext String, or "" on any failure (including
|
||||
* auth-tag mismatch). Callers MUST check for "" before trusting the result. */
|
||||
el_val_t aead_encrypt(el_val_t key_hex, el_val_t plaintext);
|
||||
el_val_t aead_decrypt(el_val_t key_hex, el_val_t nonce_hex, el_val_t ciphertext_hex);
|
||||
|
||||
/* ── Native VM builtin aliases (for compiled El source) ─────────────────────
|
||||
* These match the El VM's native_* builtins so that El source compiled
|
||||
* to C can call the same names without modification. */
|
||||
|
||||
el_val_t native_list_get(el_val_t list, el_val_t index);
|
||||
el_val_t native_list_len(el_val_t list);
|
||||
el_val_t native_list_append(el_val_t list, el_val_t elem);
|
||||
el_val_t native_list_empty(void);
|
||||
el_val_t native_list_clone(el_val_t list);
|
||||
el_val_t native_string_chars(el_val_t s);
|
||||
el_val_t native_int_to_str(el_val_t n);
|
||||
|
||||
/* ── Method-call shorthand aliases ──────────────────────────────────────────
|
||||
* The El method-call convention `obj.method(args)` compiles to
|
||||
* `method(obj, args)`. These aliases expose the runtime functions under
|
||||
* the short names that result from method calls in El source.
|
||||
*
|
||||
* Example: `myList.append(x)` → `append(myList, x)` (calls this alias)
|
||||
* `myList.len()` → `len(myList)` (calls this alias) */
|
||||
|
||||
el_val_t append(el_val_t list, el_val_t elem); /* el_list_append */
|
||||
el_val_t len(el_val_t list); /* el_list_len */
|
||||
el_val_t get(el_val_t list, el_val_t index); /* el_list_get */
|
||||
el_val_t map_get(el_val_t map, el_val_t key); /* el_map_get */
|
||||
el_val_t map_set(el_val_t map, el_val_t key, el_val_t value); /* el_map_set */
|
||||
|
||||
/* ── OTLP/HTTP Observability ─────────────────────────────────────────────── */
|
||||
/* See bottom of el_runtime.c for the implementation.
|
||||
* Configured by env vars OTLP_ENDPOINT, OTEL_SERVICE_NAME, OTEL_SERVICE_VERSION.
|
||||
* No-op when OTLP_ENDPOINT is unset. Drop-on-failure semantics. */
|
||||
/* ── Subprocess execution ────────────────────────────────────────────────── */
|
||||
el_val_t exec_command(el_val_t cmd); /* run shell command, return exit code */
|
||||
el_val_t exec_capture(el_val_t cmd); /* run shell command, capture stdout */
|
||||
el_val_t exec(el_val_t cmd); /* exec(cmd) → stdout String (30s timeout) */
|
||||
el_val_t exec_bg(el_val_t cmd); /* exec_bg(cmd) → PID String (non-blocking) */
|
||||
|
||||
el_val_t emit_log(el_val_t level, el_val_t msg, el_val_t fields_json);
|
||||
el_val_t emit_metric(el_val_t name, el_val_t value, el_val_t tags_json);
|
||||
el_val_t trace_span_start(el_val_t name);
|
||||
el_val_t trace_span_end(el_val_t span_handle);
|
||||
el_val_t emit_event(el_val_t name, el_val_t duration_ms);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user