Skip to content

server: learn a past example: /learn's messages form serves its prompt through the ordinary completion path first, then steps - #89

Open
joelteply wants to merge 2 commits into
cormac/learn-receiptsfrom
cormac/learn-past-example
Open

joelteply wants to merge 2 commits into
cormac/learn-receiptsfrom
cormac/learn-past-example

Conversation

@joelteply

Copy link
Copy Markdown

A reviewed correction settles minutes or hours after its turn, when her
slot no longer holds that prompt, and /learn refused it ("serve the prompt
again, then learn"); the dream had no way to learn a past example
(continuum S4 (f), card 13b76412; Fable's finding (f) on the S4 map).

  • The messages form of /learn now becomes a completion of the served
    prompt, one token, carrying the template-rendered reply as its learn and
    marked learn_only. update_slots serves it as it serves anything (the
    slot's own admission, the prompt cache, its checkpoints), and
    learn_if_asked steps as it finishes; send_final_response returns the
    learn outcome as its whole reply. When the slot still holds the prompt
    the cache makes this free; when not, it is one prefill. One prefill
    path, one learn path; the slot is the caller's choice (whose cached
    prompt it replaces). The token forms (reply_tokens / reply after
    n_prefix), which carry no prompt, keep requiring the slot to hold it.
  • The lost-reply binding (server: the lost-reply binding: a learn names its execution, base step and engine; a repeat is answered from its receipt, a stale one is fenced #88) is unchanged: the step still names its
    execution, base, engine and input.

Tests (IntelMac CPU, Qwen2.5-0.5B, --jinja, fresh servers):
learn-every-format.py --past-example serves an unrelated prompt on the
slot, then learns a conversation it does not hold (step 1, 11 labels, loss
2.093), then learns it again with the whole 37-token prompt kept from
cache (step 2, loss 1.299); --template-replies (text and tool-call replies
learn, the reasoning reply refused as expected) still passes.

Co-Authored-By: Claude Opus 5.5 (1M context) noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01FRQWzgSfo79JtnwZywHKrE

joelteply and others added 2 commits November 7, 2026 13:23
…t through the ordinary completion path first, then steps

A reviewed correction settles minutes or hours after its turn, when her
slot no longer holds that prompt, and /learn refused it ("serve the prompt
again, then learn"); the dream had no way to learn a past example
(continuum S4 (f), card 13b76412; Fable's finding (f) on the S4 map).

- The messages form of /learn now becomes a completion of the served
  prompt, one token, carrying the template-rendered reply as its learn and
  marked learn_only. update_slots serves it as it serves anything (the
  slot's own admission, the prompt cache, its checkpoints), and
  learn_if_asked steps as it finishes; send_final_response returns the
  learn outcome as its whole reply. When the slot still holds the prompt
  the cache makes this free; when not, it is one prefill. One prefill
  path, one learn path; the slot is the caller's choice (whose cached
  prompt it replaces). The token forms (reply_tokens / reply after
  n_prefix), which carry no prompt, keep requiring the slot to hold it.
- The lost-reply binding (#88) is unchanged: the step still names its
  execution, base, engine and input.

Tests (IntelMac CPU, Qwen2.5-0.5B, --jinja, fresh servers):
learn-every-format.py --past-example serves an unrelated prompt on the
slot, then learns a conversation it does not hold (step 1, 11 labels, loss
2.093), then learns it again with the whole 37-token prompt kept from
cache (step 2, loss 1.299); --template-replies (text and tool-call replies
learn, the reasoning reply refused as expected) still passes.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FRQWzgSfo79JtnwZywHKrE
…er the server-wide default (Fable on #89)

The messages-form /learn built its serve task from {n_predict, temperature, cache_prompt} only, so
params.lora was empty and resolved to the server-wide adapter set: a mind with a stable gene learned
her past example against the wrong model, and with id_slot defaulting to -1 the slot picker could
take another mind's idle slot and evict her cached prefix. Now the body's "lora" (her stable set,
as a completion sends it) is forwarded into the serve params; a messages-form learn without it is
refused by name whenever any adapter besides the shadow serves at a non-zero scale (read from the
set the main loop publishes, never params_base on the HTTP thread); and id_slot is required.

Test: learn-every-format.py --past-example-stable-set. Her gene is a real snapshot (a shadow trained
two steps, then /lora-adapters/snapshot; a fresh shadow is an identity adapter and would prove
nothing). A missing slot is refused; the learn under her gene has a different loss (15.82) than one
without it (2.09), so her set reaches the serve; once the gene serves at a non-zero scale, a learn
naming no set is refused. --past-example passes unchanged (CPU, Qwen2.5-0.5B, --no-repack).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FRQWzgSfo79JtnwZywHKrE
@joelteply
joelteply force-pushed the cormac/learn-receipts branch from fbed789 to 7bf7bf7 Compare November 7, 2026 19:24
@joelteply
joelteply force-pushed the cormac/learn-past-example branch from afc8d3a to d778756 Compare November 7, 2026 19:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant