Archived
engram: declare configuration once instead of at every read site
Migrates engram to the `program` block. 18 configuration variables that each
carried their default inline at the point of use now declare it in one place,
and engram declares itself a singleton.
The read sites lose their defaults entirely: `let v = env("X")` followed by
`if str_eq(v,"") { "default" } else { v }` collapses to `config("X")`. The
guide_env_or(key, dflt) helper is deleted -- its whole job was supplying a
per-site default, which is the thing being removed.
Fixes ENGRAM_DATA_DIR, which was the clearest instance of the defect. It was
read at six sites. Five were dead: `let dir_raw = env("ENGRAM_DATA_DIR")`
immediately shadowed on the next line by `engram_resolve_data_dir()`. The sixth
was live and defaulted to /tmp/engram, contradicting the canonical resolver's
$HOME/.neuron/engram -- and its consumer is the pre-destructive reseed backup,
so with ENGRAM_DATA_DIR unset the safety copy was written to ephemeral storage
while the store it protected lived elsewhere. All six now go through
engram_resolve_data_dir().
ENGRAM_DATA_DIR is deliberately NOT declared in the program block, and the
source says why: engram_resolve_data_dir() already owns it, and a second
declaration would give it two owners that can disagree -- recreating the exact
defect being removed here. A variable belongs in the block when the block would
be its only owner. HOME stays a raw env() read; it is an environment fact, not
configuration.
singleton: "engram" matters more than it looks. Today a second engram whose
bind() fails merely returns from http_serve -- after it has already replayed
the WAL and written boot-time backup files -- and then exits 0, indistinguishable
from a clean run. That is how two instances came to share one data dir. Verified
that the second instance now refuses before any side effect: with instance 1
holding the lock (lsof pid, shell pid, and lock file contents all agreeing at
5946), the second start named that pid, exited 1, and left the data directory
untouched.
Verified by bijection on the generated C: 18 config() reads, 18 declarations,
no read without a declaration and no declaration without a read. Three bad Int
values are reported in a single run rather than costing one restart each.
ENGRAM_API_KEY keeps its permissive empty default, which disables auth -- that
is pre-existing behaviour and changing it is out of scope. The source marks
making it `required` as the obvious hardening follow-up.
This commit is contained in:
+83
-36
@@ -10,10 +10,60 @@
|
|||||||
// cc -std=c11 -O2 -lcurl -lpthread -o engram server.c el_runtime.c
|
// cc -std=c11 -O2 -lcurl -lpthread -o engram server.c el_runtime.c
|
||||||
// ./engram
|
// ./engram
|
||||||
//
|
//
|
||||||
// Configuration via environment:
|
// Configuration is DECLARED, not scattered. See the `program` block below:
|
||||||
// ENGRAM_BIND — host:port (default :8742)
|
// every knob's type and default lives there and nowhere else, is resolved from
|
||||||
// ENGRAM_API_KEY — bearer auth (optional)
|
// the environment (env wins, declaration is the fallback) and validated before
|
||||||
// ENGRAM_DATA_DIR — snapshot location (default ~/.neuron/engram)
|
// any statement of this file runs. Read one with config("NAME") -> String.
|
||||||
|
//
|
||||||
|
// The one deliberate exception is ENGRAM_DATA_DIR — see the note in the block.
|
||||||
|
|
||||||
|
// ── Program declaration (cross-cutting concerns) ──────────────────────────────
|
||||||
|
//
|
||||||
|
// singleton: two engram processes against one data dir is data loss, not a
|
||||||
|
// warning. The runtime takes an exclusive flock at startup and a second start
|
||||||
|
// is refused loudly with the holder's pid.
|
||||||
|
//
|
||||||
|
// NOT declared here, on purpose: ENGRAM_DATA_DIR. Its resolution is owned by
|
||||||
|
// engram_resolve_data_dir() (el_runtime.c), which defaults to $HOME/.neuron/engram
|
||||||
|
// and fails LOUD rather than silently persisting to an ephemeral directory.
|
||||||
|
// Declaring a default for it here as well would put the data dir's fallback in
|
||||||
|
// two places — which is precisely the defect this migration removes (until
|
||||||
|
// 2026-08-15 the reseed backup path carried its own "/tmp/engram" default that
|
||||||
|
// disagreed with the resolver, so the pre-destructive safety copy landed in /tmp).
|
||||||
|
// HOME is likewise not declared: it is a genuine environment read, not a knob.
|
||||||
|
program "engram" {
|
||||||
|
singleton: "engram"
|
||||||
|
|
||||||
|
// ── Core server ──
|
||||||
|
env ENGRAM_BIND: String = ":8742"
|
||||||
|
// Default "" leaves auth DISABLED (check_auth_ok short-circuits to true on an
|
||||||
|
// empty key). That is the pre-existing behaviour and is deliberately preserved
|
||||||
|
// here; making this `required` is the obvious hardening follow-up, but it is a
|
||||||
|
// behaviour change and out of scope for this migration.
|
||||||
|
env ENGRAM_API_KEY: String = ""
|
||||||
|
|
||||||
|
// ── Feature flags (bool-ish Strings; the predicate fns below own truthiness) ──
|
||||||
|
env ENGRAM_STORE: String = "off"
|
||||||
|
env ENGRAM_WAL: String = "off"
|
||||||
|
env ENGRAM_AUTOCONNECT: String = "off"
|
||||||
|
env ENGRAM_ISE_OFFGRAPH: String = "off"
|
||||||
|
|
||||||
|
// ── ISE telemetry ──
|
||||||
|
env ENGRAM_ISE_RETENTION_MS: Int = "172800000"
|
||||||
|
|
||||||
|
// ── Guide (local Qwen3 via llama-server) ──
|
||||||
|
env GUIDE_ENABLE: String = "off"
|
||||||
|
env GUIDE_TIER_FORCE: String = ""
|
||||||
|
env GUIDE_CACHE_DIR: String = ""
|
||||||
|
env GUIDE_RAM_GB_4B: Int = "16"
|
||||||
|
env GUIDE_RAM_GB_1P7B: Int = "8"
|
||||||
|
env GUIDE_BACKEND: String = "llama-server"
|
||||||
|
env GUIDE_HOST: String = "127.0.0.1"
|
||||||
|
env GUIDE_PORT: Int = "8771"
|
||||||
|
env GUIDE_LLAMA_SERVER_BIN: String = "llama-server"
|
||||||
|
env GUIDE_NGL: Int = "99"
|
||||||
|
env GUIDE_CTX: Int = "4096"
|
||||||
|
}
|
||||||
|
|
||||||
// ── Helpers ───────────────────────────────────────────────────────────────────
|
// ── Helpers ───────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
@@ -133,7 +183,7 @@ fn route_text_health(method: String, path: String, body: String) -> String {
|
|||||||
// engram_store_enabled() in el_runtime.c EXACTLY (1 / on / true). Default off →
|
// engram_store_enabled() in el_runtime.c EXACTLY (1 / on / true). Default off →
|
||||||
// every persistence path below is byte-for-byte the historical snapshot behavior.
|
// every persistence path below is byte-for-byte the historical snapshot behavior.
|
||||||
fn store_on() -> Bool {
|
fn store_on() -> Bool {
|
||||||
let v: String = env("ENGRAM_STORE")
|
let v: String = config("ENGRAM_STORE")
|
||||||
if str_eq(v, "1") { return true }
|
if str_eq(v, "1") { return true }
|
||||||
if str_eq(v, "on") { return true }
|
if str_eq(v, "on") { return true }
|
||||||
if str_eq(v, "true") { return true }
|
if str_eq(v, "true") { return true }
|
||||||
@@ -162,7 +212,6 @@ fn persist_canonical() -> Int {
|
|||||||
if store_on() {
|
if store_on() {
|
||||||
return engram_store_checkpoint()
|
return engram_store_checkpoint()
|
||||||
}
|
}
|
||||||
let dir_raw: String = env("ENGRAM_DATA_DIR")
|
|
||||||
let dir: String = engram_resolve_data_dir()
|
let dir: String = engram_resolve_data_dir()
|
||||||
// (2026-08-10 self-review) This returned a hardcoded 1, which made every
|
// (2026-08-10 self-review) This returned a hardcoded 1, which made every
|
||||||
// caller's `let saved: Int = persist_canonical()` a dead variable — six
|
// caller's `let saved: Int = persist_canonical()` a dead variable — six
|
||||||
@@ -176,7 +225,7 @@ fn persist_canonical() -> Int {
|
|||||||
// per-write full-snapshot behavior. When ON, structural mutations append O(1)
|
// per-write full-snapshot behavior. When ON, structural mutations append O(1)
|
||||||
// WAL records instead of rewriting the whole graph, with threshold compaction.
|
// WAL records instead of rewriting the whole graph, with threshold compaction.
|
||||||
fn wal_on() -> Bool {
|
fn wal_on() -> Bool {
|
||||||
str_eq(env("ENGRAM_WAL"), "on")
|
str_eq(config("ENGRAM_WAL"), "on")
|
||||||
}
|
}
|
||||||
|
|
||||||
// autoconnect_on — ENGRAM_AUTOCONNECT. Will's rule: "we shouldn't be inserting
|
// autoconnect_on — ENGRAM_AUTOCONNECT. Will's rule: "we shouldn't be inserting
|
||||||
@@ -184,7 +233,7 @@ fn wal_on() -> Bool {
|
|||||||
// edge (kNN over embeddings) so no content node enters the graph edgeless.
|
// edge (kNN over embeddings) so no content node enters the graph edgeless.
|
||||||
// Default OFF -> byte-identical to prior behavior (node created, no auto edges).
|
// Default OFF -> byte-identical to prior behavior (node created, no auto edges).
|
||||||
fn autoconnect_on() -> Bool {
|
fn autoconnect_on() -> Bool {
|
||||||
let v: String = env("ENGRAM_AUTOCONNECT")
|
let v: String = config("ENGRAM_AUTOCONNECT")
|
||||||
if str_eq(v, "1") { return true }
|
if str_eq(v, "1") { return true }
|
||||||
if str_eq(v, "on") { return true }
|
if str_eq(v, "on") { return true }
|
||||||
if str_eq(v, "true") { return true }
|
if str_eq(v, "true") { return true }
|
||||||
@@ -197,7 +246,7 @@ fn autoconnect_on() -> Bool {
|
|||||||
// separate state-event log tier instead of the node graph. Default OFF -> ISEs
|
// separate state-event log tier instead of the node graph. Default OFF -> ISEs
|
||||||
// remain graph nodes exactly as before (with 48h prune).
|
// remain graph nodes exactly as before (with 48h prune).
|
||||||
fn ise_offgraph_on() -> Bool {
|
fn ise_offgraph_on() -> Bool {
|
||||||
let v: String = env("ENGRAM_ISE_OFFGRAPH")
|
let v: String = config("ENGRAM_ISE_OFFGRAPH")
|
||||||
if str_eq(v, "1") { return true }
|
if str_eq(v, "1") { return true }
|
||||||
if str_eq(v, "on") { return true }
|
if str_eq(v, "on") { return true }
|
||||||
if str_eq(v, "true") { return true }
|
if str_eq(v, "true") { return true }
|
||||||
@@ -358,7 +407,6 @@ fn route_scan_nodes(method: String, path: String, body: String) -> String {
|
|||||||
// process ever booted with a partial/empty store, the first read request
|
// process ever booted with a partial/empty store, the first read request
|
||||||
// clobbered the good snapshot. Read routes must never write the canonical path.)
|
// clobbered the good snapshot. Read routes must never write the canonical path.)
|
||||||
fn route_scan_edges(method: String, path: String, body: String) -> String {
|
fn route_scan_edges(method: String, path: String, body: String) -> String {
|
||||||
let dir_raw: String = env("ENGRAM_DATA_DIR")
|
|
||||||
let dir: String = engram_resolve_data_dir()
|
let dir: String = engram_resolve_data_dir()
|
||||||
let snap_path: String = dir + "/.scan-export.json"
|
let snap_path: String = dir + "/.scan-export.json"
|
||||||
engram_save(snap_path)
|
engram_save(snap_path)
|
||||||
@@ -519,7 +567,6 @@ fn route_forget(method: String, path: String, body: String) -> String {
|
|||||||
|
|
||||||
fn route_save(method: String, path: String, body: String) -> String {
|
fn route_save(method: String, path: String, body: String) -> String {
|
||||||
let p_raw: String = json_get_string(body, "path")
|
let p_raw: String = json_get_string(body, "path")
|
||||||
let dir_raw: String = env("ENGRAM_DATA_DIR")
|
|
||||||
let dir: String = engram_resolve_data_dir()
|
let dir: String = engram_resolve_data_dir()
|
||||||
let p: String = if str_eq(p_raw, "") { dir + "/snapshot.json" } else { p_raw }
|
let p: String = if str_eq(p_raw, "") { dir + "/snapshot.json" } else { p_raw }
|
||||||
// (2026-08-10 self-review) engram_save returns 0 on an empty path and the
|
// (2026-08-10 self-review) engram_save returns 0 on an empty path and the
|
||||||
@@ -603,7 +650,6 @@ fn route_drift(method: String, path: String, body: String) -> String {
|
|||||||
|
|
||||||
fn route_load(method: String, path: String, body: String) -> String {
|
fn route_load(method: String, path: String, body: String) -> String {
|
||||||
let p_raw: String = json_get_string(body, "path")
|
let p_raw: String = json_get_string(body, "path")
|
||||||
let dir_raw: String = env("ENGRAM_DATA_DIR")
|
|
||||||
let dir: String = engram_resolve_data_dir()
|
let dir: String = engram_resolve_data_dir()
|
||||||
let p: String = if str_eq(p_raw, "") { dir + "/snapshot.json" } else { p_raw }
|
let p: String = if str_eq(p_raw, "") { dir + "/snapshot.json" } else { p_raw }
|
||||||
// (2026-08-10 self-review) This was a stub response over the single most
|
// (2026-08-10 self-review) This was a stub response over the single most
|
||||||
@@ -674,7 +720,6 @@ fn route_embed_backfill(method: String, path: String, body: String) -> String {
|
|||||||
// (it skips nodes already present by ID). Auth-exempt: same-host internal call.
|
// (it skips nodes already present by ID). Auth-exempt: same-host internal call.
|
||||||
// (2026-06-27 self-review: added this route to fix silent 10-min sync failures)
|
// (2026-06-27 self-review: added this route to fix silent 10-min sync failures)
|
||||||
fn route_sync(method: String, path: String, body: String) -> String {
|
fn route_sync(method: String, path: String, body: String) -> String {
|
||||||
let dir_raw: String = env("ENGRAM_DATA_DIR")
|
|
||||||
let dir: String = engram_resolve_data_dir()
|
let dir: String = engram_resolve_data_dir()
|
||||||
// 2026-07-21 self-review: export to a scratch path, never the canonical
|
// 2026-07-21 self-review: export to a scratch path, never the canonical
|
||||||
// snapshot.json — read routes must not be able to clobber the good snapshot.
|
// snapshot.json — read routes must not be able to clobber the good snapshot.
|
||||||
@@ -750,8 +795,12 @@ fn route_reseed_nodes(method: String, path: String, body: String) -> String {
|
|||||||
if str_eq(p, "") { return err_json("path is required") }
|
if str_eq(p, "") { return err_json("path is required") }
|
||||||
if str_eq(fs_read(p), "") { return err_json("file missing or empty") }
|
if str_eq(fs_read(p), "") { return err_json("file missing or empty") }
|
||||||
|
|
||||||
let dir_raw: String = env("ENGRAM_DATA_DIR")
|
// (2026-08-15) This site carried its own "/tmp/engram" fallback, which
|
||||||
let dir: String = if str_eq(dir_raw, "") { "/tmp/engram" } else { dir_raw }
|
// DISAGREED with engram_resolve_data_dir() ($HOME/.neuron/engram, fail-loud).
|
||||||
|
// The consumer is the pre-destructive backup below, so with ENGRAM_DATA_DIR
|
||||||
|
// unset the safety copy taken before a reseed landed in an ephemeral /tmp
|
||||||
|
// while the store it was protecting lived elsewhere. One owner, one answer.
|
||||||
|
let dir: String = engram_resolve_data_dir()
|
||||||
let backup: String = dir + "/.reseed-backup.json"
|
let backup: String = dir + "/.reseed-backup.json"
|
||||||
|
|
||||||
let replace_raw: String = json_get_raw(body, "replace")
|
let replace_raw: String = json_get_raw(body, "replace")
|
||||||
@@ -843,8 +892,7 @@ fn route_emit_ise(method: String, path: String, body: String) -> String {
|
|||||||
sal, imp, conf,
|
sal, imp, conf,
|
||||||
"Episodic", "[\"internal-state\",\"InternalStateEvent\"]"
|
"Episodic", "[\"internal-state\",\"InternalStateEvent\"]"
|
||||||
)
|
)
|
||||||
let ret_raw: String = env("ENGRAM_ISE_RETENTION_MS")
|
let ret_ms: Int = str_to_int(config("ENGRAM_ISE_RETENTION_MS"))
|
||||||
let ret_ms: Int = if str_eq(ret_raw, "") { 172800000 } else { str_to_int(ret_raw) }
|
|
||||||
let pruned: Int = engram_prune_telemetry(ret_ms)
|
let pruned: Int = engram_prune_telemetry(ret_ms)
|
||||||
"{\"ok\":true,\"id\":\"" + id + "\",\"pruned\":" + int_to_str(pruned) + "}"
|
"{\"ok\":true,\"id\":\"" + id + "\",\"pruned\":" + int_to_str(pruned) + "}"
|
||||||
}
|
}
|
||||||
@@ -1093,14 +1141,12 @@ fn route_correspondence_beat(method: String, path: String, body: String) -> Stri
|
|||||||
// turns native thinking ON: the response carries reasoning_content (the thinking)
|
// turns native thinking ON: the response carries reasoning_content (the thinking)
|
||||||
// alongside content (the answer).
|
// alongside content (the answer).
|
||||||
|
|
||||||
fn guide_env_or(key: String, dflt: String) -> String {
|
// (2026-08-15) guide_env_or(key, dflt) lived here. Its whole job was supplying a
|
||||||
let v: String = env(key)
|
// per-call-site default, which is now the program block's job — every GUIDE_* knob
|
||||||
if str_eq(v, "") { return dflt }
|
// is declared once at the top of this file and read straight through config().
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
fn guide_enabled() -> Bool {
|
fn guide_enabled() -> Bool {
|
||||||
let v: String = env("GUIDE_ENABLE")
|
let v: String = config("GUIDE_ENABLE")
|
||||||
if str_eq(v, "1") { return true }
|
if str_eq(v, "1") { return true }
|
||||||
if str_eq(v, "on") { return true }
|
if str_eq(v, "on") { return true }
|
||||||
if str_eq(v, "true") { return true }
|
if str_eq(v, "true") { return true }
|
||||||
@@ -1145,15 +1191,15 @@ fn guide_probe_metal() -> Bool {
|
|||||||
|
|
||||||
// ── 2. Tier selection (config-driven thresholds, spec-autoselected) ────────────
|
// ── 2. Tier selection (config-driven thresholds, spec-autoselected) ────────────
|
||||||
fn guide_threshold_4b() -> Int {
|
fn guide_threshold_4b() -> Int {
|
||||||
return str_to_int(guide_env_or("GUIDE_RAM_GB_4B", "16"))
|
return str_to_int(config("GUIDE_RAM_GB_4B"))
|
||||||
}
|
}
|
||||||
fn guide_threshold_1p7b() -> Int {
|
fn guide_threshold_1p7b() -> Int {
|
||||||
return str_to_int(guide_env_or("GUIDE_RAM_GB_1P7B", "8"))
|
return str_to_int(config("GUIDE_RAM_GB_1P7B"))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GUIDE_TIER_FORCE overrides the spec autoselect (used to prove cheaply on 0.6b).
|
// GUIDE_TIER_FORCE overrides the spec autoselect (used to prove cheaply on 0.6b).
|
||||||
fn guide_select_tier(ram_gb: Int) -> String {
|
fn guide_select_tier(ram_gb: Int) -> String {
|
||||||
let forced: String = env("GUIDE_TIER_FORCE")
|
let forced: String = config("GUIDE_TIER_FORCE")
|
||||||
if !str_eq(forced, "") { return forced }
|
if !str_eq(forced, "") { return forced }
|
||||||
if ram_gb >= guide_threshold_4b() { return "4b" }
|
if ram_gb >= guide_threshold_4b() { return "4b" }
|
||||||
if ram_gb >= guide_threshold_1p7b() { return "1.7b" }
|
if ram_gb >= guide_threshold_1p7b() { return "1.7b" }
|
||||||
@@ -1173,8 +1219,10 @@ fn guide_file(tier: String) -> String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn guide_cache_dir() -> String {
|
fn guide_cache_dir() -> String {
|
||||||
let c: String = env("GUIDE_CACHE_DIR")
|
let c: String = config("GUIDE_CACHE_DIR")
|
||||||
if !str_eq(c, "") { return c }
|
if !str_eq(c, "") { return c }
|
||||||
|
// HOME stays a raw env() read: it is the ambient environment, not a knob of
|
||||||
|
// this program, and it is deliberately absent from the program block.
|
||||||
let home: String = env("HOME")
|
let home: String = env("HOME")
|
||||||
if !str_eq(home, "") { return home + "/.neuron/guide/models" }
|
if !str_eq(home, "") { return home + "/.neuron/guide/models" }
|
||||||
return engram_resolve_data_dir() + "/guide-models"
|
return engram_resolve_data_dir() + "/guide-models"
|
||||||
@@ -1215,9 +1263,9 @@ fn guide_fetch(tier: String) -> Bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ── 4/5. Backend abstraction + BIND as an engageable interlocutor ──────────────
|
// ── 4/5. Backend abstraction + BIND as an engageable interlocutor ──────────────
|
||||||
fn guide_backend() -> String { return guide_env_or("GUIDE_BACKEND", "llama-server") }
|
fn guide_backend() -> String { return config("GUIDE_BACKEND") }
|
||||||
fn guide_host() -> String { return guide_env_or("GUIDE_HOST", "127.0.0.1") }
|
fn guide_host() -> String { return config("GUIDE_HOST") }
|
||||||
fn guide_port() -> String { return guide_env_or("GUIDE_PORT", "8771") }
|
fn guide_port() -> String { return config("GUIDE_PORT") }
|
||||||
fn guide_base_url() -> String { return "http://" + guide_host() + ":" + guide_port() }
|
fn guide_base_url() -> String { return "http://" + guide_host() + ":" + guide_port() }
|
||||||
|
|
||||||
// guide_healthy — is the guide present and answering? llama-server's /health
|
// guide_healthy — is the guide present and answering? llama-server's /health
|
||||||
@@ -1235,9 +1283,9 @@ fn guide_healthy() -> Bool {
|
|||||||
fn guide_load(tier: String) -> Bool {
|
fn guide_load(tier: String) -> Bool {
|
||||||
if guide_healthy() { return true }
|
if guide_healthy() { return true }
|
||||||
let path: String = guide_model_path(tier)
|
let path: String = guide_model_path(tier)
|
||||||
let bin: String = guide_env_or("GUIDE_LLAMA_SERVER_BIN", "llama-server")
|
let bin: String = config("GUIDE_LLAMA_SERVER_BIN")
|
||||||
let ngl: String = guide_env_or("GUIDE_NGL", "99")
|
let ngl: String = config("GUIDE_NGL")
|
||||||
let ctx: String = guide_env_or("GUIDE_CTX", "4096")
|
let ctx: String = config("GUIDE_CTX")
|
||||||
let logf: String = guide_cache_dir() + "/llama-server." + guide_port() + ".log"
|
let logf: String = guide_cache_dir() + "/llama-server." + guide_port() + ".log"
|
||||||
let cmd: String = bin + " -m '" + path + "' --host " + guide_host() + " --port " + guide_port() + " -c " + ctx + " -ngl " + ngl + " --jinja >> '" + logf + "' 2>&1"
|
let cmd: String = bin + " -m '" + path + "' --host " + guide_host() + " --port " + guide_port() + " -c " + ctx + " -ngl " + ngl + " --jinja >> '" + logf + "' 2>&1"
|
||||||
let pid: String = exec_bg(cmd)
|
let pid: String = exec_bg(cmd)
|
||||||
@@ -1633,7 +1681,7 @@ fn route_supersede(method: String, path: String, body: String) -> String {
|
|||||||
// ── Auth ──────────────────────────────────────────────────────────────────────
|
// ── Auth ──────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
fn check_auth_ok(method: String, body: String) -> Bool {
|
fn check_auth_ok(method: String, body: String) -> Bool {
|
||||||
let key: String = env("ENGRAM_API_KEY")
|
let key: String = config("ENGRAM_API_KEY")
|
||||||
if str_eq(key, "") { return true }
|
if str_eq(key, "") { return true }
|
||||||
// Read-only methods don't require auth. Until http_serve surfaces
|
// Read-only methods don't require auth. Until http_serve surfaces
|
||||||
// request headers we can't accept a Bearer token cleanly; mutating
|
// request headers we can't accept a Bearer token cleanly; mutating
|
||||||
@@ -1896,8 +1944,7 @@ fn handle_request(method: String, path: String, body: String) -> String {
|
|||||||
|
|
||||||
// ── Entry ─────────────────────────────────────────────────────────────────────
|
// ── Entry ─────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
let bind_raw: String = env("ENGRAM_BIND")
|
let bind_str: String = config("ENGRAM_BIND")
|
||||||
let bind_str: String = if str_eq(bind_raw, "") { ":8742" } else { bind_raw }
|
|
||||||
let port: Int = parse_port(bind_str)
|
let port: Int = parse_port(bind_str)
|
||||||
|
|
||||||
// On startup, try to load any existing snapshot (best effort).
|
// On startup, try to load any existing snapshot (best effort).
|
||||||
|
|||||||
Reference in New Issue
Block a user