// surface.el — the RESHAPED Neuron surface as EL-NATIVE DECORATED COMPONENTS.
//
// Design: artifact 0e828907 + design-brief 2b8078cf §5. THE DECORATION IS THE API.
// Each op is one function decorated with (a) its @route — codegen synthesizes the
// HTTP dispatcher (el_route_dispatch), no hand-written 90-branch handle_request —
// and (b) its VBD role — @accessor (engram I/O) or @manager (agentic orchestration
// + sole DHARMA emitter). Handlers call the engram IN-PROCESS via engram_* builtins
// (NOT http_get: the old MCP-wrapper http idiom existed only because it was a
// separate process; compiled into the engram, the geometry is a direct call).
//
// This file is designed to be INCLUDED IN the engram server (engram/src/server.el)
// so the engram_* builtins + server helpers (query_param, json_get_string,
// extract_id, err_json, engram_node_full, persist_node, ...) link in-process.
//
// Handler contract (from the @route codegen): uniform (method, path, body)->String.
//
// Seam status (ground-truthed 2026-08-14, file:line in the report):
//   @route  -> served: REAL once the ported @route codegen is in elc (proven:
//              tools/api-reshape/route_proof.el serves decorated handlers on :8951).
//   @manager dharma_emit -> bus: REAL today (explicit call; @manager may emit).
//              STAGED codegen change makes it AUTOMATIC at the boundary (report §diff),
//              sharing the one dharma_* transport the swarm (wt/swarm-ccr) uses.
//   @accessor telemetry (strengthen/afferent/chronoception): fires inside the
//              engram builtins today; STAGED to also fire at the decorated boundary.

// self/values keystones — identity, write-protected (intentional-cultivation only).
fn is_identity_id(id: String) -> Bool {
    if str_eq(id, "kn-efeb4a5b-5aff-4759-8a97-7233099be6ee") { return true }
    if str_eq(id, "kn-5b606390-a52d-4ca2-8e0e-eba141d13440") { return true }
    return false
}
fn type_node_type(t: String) -> String {
    if str_eq(t, "knowledge") { return "Knowledge" }
    if str_eq(t, "artifact") { return "Artifact" }
    if str_eq(t, "backlog") { return "WorkItem" }
    if str_eq(t, "process") { return "Process" }
    if str_eq(t, "state") { return "InternalStateEvent" }
    return "Memory"
}

// ── LAYER 1 — geometry ops (@accessor: engram I/O, in-process) ────────────────

// read — THE VANTAGE-READ. re-origin + aperture -> BOUNDED slice. type=edges reads
// the neighborhood; a concept vantage reads salience-ranked geometry (limit=aperture).
@route("/api/read", "GET")
@accessor
fn op_read(method: String, path: String, body: String) -> String {
    let vantage: String = query_param(path, "vantage")
    if str_eq(vantage, "") { return err_json("read: vantage required") }
    let typ: String = query_param(path, "type")
    let k: Int = query_int(path, "k", 12)          // aperture (bounded by construction)
    if str_eq(typ, "edges") { return engram_neighbors_json(vantage) }
    if str_starts_with(vantage, "kn-") { return engram_neighbors_json(vantage) }
    return engram_retrieve_geometric_json(vantage, k)
}

// write — add a node; type -> node_type. Identity types refused.
@route("/api/write", "POST")
@accessor
fn op_write(method: String, path: String, body: String) -> String {
    let content: String = json_get_string(body, "content")
    if str_eq(content, "") { return err_json("write: content required") }
    let typ: String = json_get_string(body, "type")
    if str_eq(typ, "self") { return err_json("write: identity is write-protected -> intentional-cultivation") }
    if str_eq(typ, "values") { return err_json("write: identity is write-protected -> intentional-cultivation") }
    let tags: String = json_get_string(body, "tags")
    let imp: Float = json_get_float(body, "importance")
    let id: String = engram_node_full(content, type_node_type(typ), content, 0.5, imp, 1.0, "Working", tags)
    let saved: Int = persist_node(id)
    return "{\"id\":\"" + id + "\",\"type\":\"" + typ + "\"}"
}

// relate — typed edge. Refused if either endpoint is an identity keystone.
@route("/api/relate", "POST")
@accessor
fn op_relate(method: String, path: String, body: String) -> String {
    let from_id: String = json_get_string(body, "from")
    let to_id: String = json_get_string(body, "to")
    if str_eq(from_id, "") { return err_json("relate: from required") }
    if str_eq(to_id, "") { return err_json("relate: to required") }
    if is_identity_id(from_id) { return err_json("relate: identity keystone write-protected") }
    if is_identity_id(to_id) { return err_json("relate: identity keystone write-protected") }
    let rel_raw: String = json_get_string(body, "relationship")
    let rel: String = if str_eq(rel_raw, "") { "associates" } else { rel_raw }
    let ec0: Int = engram_edge_count()
    engram_connect(from_id, to_id, 0.5, rel)
    let saved: Int = persist_edges_since(ec0)
    return "{\"ok\":true,\"from\":\"" + from_id + "\",\"to\":\"" + to_id + "\",\"relationship\":\"" + rel + "\"}"
}

// supersede — IMMUTABLE. tombstone (marker + edge, original kept) | evolve (new + edge).
@route("/api/supersede", "POST")
@accessor
fn op_supersede(method: String, path: String, body: String) -> String {
    let id: String = json_get_string(body, "id")
    if str_eq(id, "") { return err_json("supersede: id required") }
    if is_identity_id(id) { return err_json("supersede: identity keystone write-protected") }
    let action: String = json_get_string(body, "action")
    if str_eq(action, "tombstone") {
        let tomb: String = engram_node_full("tombstone:" + id, "Tombstone", "tombstone:" + id, 0.1, 0.1, 1.0, "Episodic", "[\"tombstone\"]")
        engram_connect(tomb, id, 1.0, "tombstones")     // original node retained (immutable)
        let s: Int = persist_node(tomb)
        return "{\"ok\":true,\"tombstoned\":\"" + id + "\",\"tombstone_id\":\"" + tomb + "\"}"
    }
    let content: String = json_get_string(body, "content")
    if str_eq(content, "") { return err_json("supersede(evolve): content required") }
    let new_id: String = engram_node_full(content, "Memory", content, 0.5, 0.5, 1.0, "Working", "")
    let sv: Int = persist_node(new_id)
    engram_connect(new_id, id, 1.0, "supersedes")       // old node retained (immutable)
    let sv2: Int = persist_edges_since(engram_edge_count() - 1)
    return "{\"new_id\":\"" + new_id + "\",\"supersedes\":\"" + id + "\"}"
}

// ── LAYER 2 — primitive agentic tools (@manager: orchestration + DHARMA emit) ──
// think is the one operation; faculty is its steering label. Each @manager op
// emits on the dharma_* bus (the same transport the swarm peers use). When the
// staged boundary-injection lands, these explicit emits become automatic.

@route("/api/think", "GET")
@manager
fn op_think(method: String, path: String, body: String) -> String {
    let seeds: String = query_param(path, "seeds")     // CSV node-ids (the anchor)
    if str_eq(seeds, "") { return err_json("think: seeds (node-id anchor) required") }
    let f_raw: String = query_param(path, "faculty")
    let f: String = if str_eq(f_raw, "") { "reason" } else { f_raw }
    dharma_emit("neuron.think", "{\"seeds\":\"" + seeds + "\",\"faculty\":\"" + f + "\"}")
    return engram_think_json(seeds, f)
}

@route("/api/attend", "POST")
@manager
fn op_attend(method: String, path: String, body: String) -> String {
    let node: String = json_get_string(body, "node")
    if str_eq(node, "") { return err_json("attend: node (region) required") }
    let observer: String = json_get_string(body, "observer")
    let salience: String = json_get_string(body, "salience")
    dharma_emit("neuron.attend", "{\"node\":\"" + node + "\"}")
    return engram_attend_json(node, observer, salience)
}

@route("/api/ground", "POST")
@manager
fn op_ground(method: String, path: String, body: String) -> String {
    let claim: String = json_get_string(body, "claim")       // node-id region
    let evidence: String = json_get_string(body, "evidence") // node-id region
    if str_eq(claim, "") { return err_json("ground: claim required") }
    if str_eq(evidence, "") { return err_json("ground: evidence required") }
    let for_whom: String = json_get_string(body, "for_whom")
    dharma_emit("neuron.ground", "{\"claim\":\"" + claim + "\"}")
    return engram_ground_json(claim, evidence, for_whom)
}

// learn — the reflexive correspondence-beat: calibrate the steering-prior (Stance).
@route("/api/learn", "POST")
@manager
fn op_learn(method: String, path: String, body: String) -> String {
    let seeds: String = json_get_string(body, "seeds")
    if str_eq(seeds, "") { return err_json("learn: seeds required") }
    let f_raw: String = json_get_string(body, "faculty")
    let f: String = if str_eq(f_raw, "") { "induce" } else { f_raw }
    let keystone: String = json_get_string(body, "keystone")
    dharma_emit("neuron.learn", "{\"seeds\":\"" + seeds + "\",\"faculty\":\"" + f + "\"}")
    return engram_correspondence_beat_json(seeds, f, keystone)
}
