get_advice is not listed over MCP and POST /advice answers
503 (“advice is routed by a model: this server has none”).
Sessions
A session is one conversation, start to end.momentsays where in the task the agent is.start(the default) routes the task to its note.fork,stuckanddonere-read the note the session was already served (steps and pitfalls, pitfalls, or pitfalls and verification), with no model call: the person’s own note and the team’s answer both, when they were served together.nextis sent by the Claude Code hooks when a step finishes.- Each note is served once per session; asked again, the answer says it was given earlier.
get_advicewith nosession_id, from a person, opens a session and returns its id.- A session nobody ends is ended after
AMPUP_MEMORY_SESSION_IDLE_SECS(1800) without a step, with the last conversation it was sent as its transcript. - The opening context, transcript and conversation are the caller’s own episodes, readable by them alone, with
secret-looking words redacted. At most
AMPUP_MEMORY_SESSIONS_PER_DAY(1000) sessions a person a day.
Judging
When a session that was served advice ends, a judge model reads its notes and transcript (fenced as data) and says, per note, whether the agent applied it and whether it helped, and whether the session succeeded, failed or is unclear. A session’s judged outcome is its reward when the agent gave none. Each note keeps a tally (served, applied, helped, not helped), counting each person’s latest judged session only.Holdout arm
AMPUP_MEMORY_ADVICE_HOLDOUT(0 to 1, default 0): that share of new sessions is routed but served nothing. Comparing served against withheld outcomes measures lift.
Evidence
Every note learning writes is served to everyone it is learned for; there is no trial arm and no gate. A note is reported ratified once it helped more people than it didn’t, counted by each person’s latest judged session, up to the scope’s evidence bar: the team’sadvice_evidence setting, else the org’s, else AMPUP_MEMORY_ADVICE_EVIDENCE
(default 3). The bar is reported only (list_advice, ampup-memory doctor); it changes nothing that is served.
Runs are not evidence; only judged sessions are.
Runs and rewards
A run is one task an agent did, recorded by a harness, a CI job or a script.POST /runs {task, trace, used?, outcome?, advice?}.traceis at most 20,000 characters and is the caller’s own episode.adviceis the situation keyget_advicenamed, so a run says what it was served (several keys separated by;).POST /runs/reward {run_id, reward: -1..1, reason?}. Only the recorder rewards its own run.- Batches.
POST /runs {"runs": [...]}takes up to 1,000 runs and 16 MiB, each with an inlinerewardandreason. Every run is checked before any is written; one bad run refuses the batch. Batch run ids are derived from the runs’ content, so loading the same runs into a fresh store gives the same ids.POST /runs/reward {"rewards": [...]}rewards up to 1,000 runs at once. - From a file.
ampup-memory runs load <scope> runs.jsonl --as <user>records one run a line as one batch. With--local <dir>(server stopped) it writes aserve --localstore. - Limits:
AMPUP_MEMORY_RUNS_PER_DAY(100) runs andAMPUP_MEMORY_LOG_PER_DAY(1000) answer-log entries per person a day. - Unrewarded runs older than
AMPUP_MEMORY_ADVICE_JUDGE_AFTER_SECS(1800) are judged by a model (1, -1 or “can’t tell”); a recorder’s own reward later replaces the judgement.AMPUP_MEMORY_ADVICE_JUDGE=offturns that off.ampup-memory qa-log <scope>shows each judgement.
How notes are learned
- Sort. Rewarded runs and sessions are sorted, 60 tasks a batch, into a map: category, then situation. Only the task text is shown to the model.
- Link. Each situation is linked to up to three compiled procedures that serve it.
- Write. For each situation with at least
--min-wrong(default 2) runs that went wrong, the learning model reads up to 40 of its runs (newest wrong and newest right, at least 10 right when it has them) and the linked procedures, and writes one note: When, Steps, Pitfalls, Evidence. It is a general procedure and never names a record’s values. - Keep. Notes are versioned documents:
advice/index,advice/map,advice/<category>/<situation>. A note is rewritten only afterAMPUP_MEMORY_ADVICE_NOTE_MIN_NEW(5) new runs or 2 new wrong ones.
- Team notes need people. A team note is learned only from situations whose runs come from at least
advice_learn_peoplepeople (AMPUP_MEMORY_ADVICE_LEARN_PEOPLE, default 3, never below 2). One person’s traces can’t make a team note. - Personal notes. A person with at least
AMPUP_MEMORY_ADVICE_MIN_NEW(10) rewarded runs or sessions of their own also gets notes learned from those alone, served to them first, with no evidence bar. - On its own. Where an org’s or team’s admins set
advice: true,servelearns everyAMPUP_MEMORY_ADVICE_SECS(600) onceAMPUP_MEMORY_ADVICE_MIN_NEW(10) new rewarded runs are in.serve --locallearns in its own scope without the setting.AMPUP_MEMORY_ADVICE_LEARN=offstops the timer;AMPUP_MEMORY_ADVICE=offstops learning. - By hand.
ampup-memory advice <scope> [--acl …] [--min-wrong N] [--local DIR], or/admin {"op": "learn_advice", "org", "team"?}on a server. - Audience. Learning reads every rewarded run in the scope, so only an org’s admins start it or turn it on,
and the notes are written for the audience they name (
--acl, default*).
Trust
A reward is its recorder’s word, and the learning model reads reasons and traces as evidence. Anyone who may record runs in a scope can steer what its notes say. Learn advice in scopes whose writers you trust, and read the notes (get_episode {document: "advice/…"}) before relying on them. A judged reward is a model’s opinion of the
trace’s end, not the outcome.
Curation (opt-in)
advice_curation: true (or AMPUP_MEMORY_ADVICE_CURATION=on) adds three things to each learn:
- Withhold by reward. A note is withheld when the runs served it score lower than its situation’s other runs,
with at least
AMPUP_MEMORY_ADVICE_RETIRE_MIN(8) runs a side, a margin ofAMPUP_MEMORY_ADVICE_RETIRE_MARGIN(0.2) and a one-sided z of at least 1.645. Only rewards somebody gave count, unlessAMPUP_MEMORY_ADVICE_RETIRE_JUDGED=on. - Edit, don’t rewrite. The model returns item edits (add, modify, remove); an edit that would drop more than a quarter of the note’s words is refused.
- Merge. Situations that are the same task under two names are merged; the old names stay as aliases.
What get_advice serves
The routing model reads one line per kind of task the caller may be advised on and names one, or none.
- A situation with a note: the note alone (the default).
advice_procedures: true, or"procedures": trueon a call, serves the note with its linked procedures. - A situation with no servable note: up to two linked procedures in full.
- A compiled skill no situation links: its procedure.
Situation: <key>, then Skill: <key> (version <n>), learned from <n> runs ….
POST /advice answers {situation, advice, skills}; each skill says from: "runs" or from: "documents".
Options on POST /advice: format (notes or checklist; also AMPUP_MEMORY_ADVICE_FORMAT), max_chars (at
least 500), procedures, and "notes": false to serve compiled procedures only (an ablation a caller runs
itself).
- Large libraries. Above
AMPUP_MEMORY_ADVICE_ROUTE_SHORTLIST(60) lines, lines are first ranked against the question (BM25 and embedding, fused by reciprocal rank) and the router sees the best 60. - Prompt caching. The index goes in the request’s system part, marked cacheable where the provider needs a mark, so repeated questions reuse it.
- Lenient reading. The router’s reply is matched by key, by key without its prefix, or by readable name.
Review checks by file (POST /advice with files)
{"files", "title"?, "pr"?, "repo"?, "issues"?, "top"?} returns review checks for a change: skills whose source
pull requests touched the same files, ranked by shared files (rare files count most), condensed by the routing
model into 2 to 8 bullets. Answers {checks, skills, issues}. No session.
Similar past errors (opt-in)
Witherror_leads: true on an org or team, a question that carries an error (a Sentry short id or link, an
exception and message, or stack frames) also gets up to three leads: similar past errors from the caller’s
sentry: episodes and the merged github: pull requests that name them. Matching is by exception, culprit,
message, shared frames and files, fused with BM25. No model is called. Answers carry leads.
Public capabilities
get_advice and POST /advice may also suggest a public skill, plugin or MCP server from a small reviewed catalog
(catalog version 2026-11-08) when a decisions model (AMPUP_MEMORY_DECIDE) is configured and is at least 0.9
confident. Send available_capabilities to suppress what the agent already has. public_capabilities: false per
call, or AMPUP_MEMORY_PUBLIC_CAPABILITIES=off, turns them off. They are suggestions, not installs.
Procedures: AIP skills and step graphs
A scope’s chosen documents are compiled into a skill library as they come in. A skill is what an agent should do in one situation the documents describe:- the situation (When);
- numbered steps with the exact tools, values and checks the sources give;
- an If line per edge case;
- the sources it rests on.
skills/<slug>, aip/<slug>, skills/index.
- Chosen, never on by default. A scope compiles from its
compile_sources(source prefixes, or*), elseAMPUP_MEMORY_COMPILE_SOURCES. With none, nothing compiles. Versioned documents are never compiled. - Batches. Sources go to the model 12 at a time (at most 60,000 characters), oldest first; each round sees the
library the last one left. Tune with
AMPUP_MEMORY_COMPILE_BATCH,AMPUP_MEMORY_COMPILE_BATCH_CHARS,AMPUP_MEMORY_COMPILE_MAX_TOKENSandAMPUP_MEMORY_COMPILE_PARALLEL. - Grounded. Sources go in under handles (
SRC1, …); a skill that cites none is dropped, and a graph that fails validation isn’t written. - Audiences. Sources with different ACLs never share a batch. A skill is readable by exactly its sources’ ACL.
compile_kind: errorstells the compiler its sources are error reports, so each skill’s When names the exception and message.AMPUP_MEMORY_COMPILE=offturns compiling off for the server;set_settings {"compile": false}for one org or team.
Models
The learning models run rarely; what they write is read on every later task. Per-call work runs on the small model.
Backends and credentials are in configuration.md.
Model-call cache
Every model call can be answered from an earlier identical request (backend, model and request body, keyed by SHA-256). Builds (compile, advice, extract, aggregate, serve --local) keep replies in
~/.cache/memstore/model-calls by default, so rebuilding the same memory pays nothing for calls already made.
Servers keep none unless AMPUP_MEMORY_MODEL_CACHE names a location (a directory, gs://, s3://, file://, or
off). The cache keeps replies after their data is forgotten: a deployment that must erase data leaves it off or
clears it too.