skip to content
Memory

Parallax

Memory

A lesson comes only from an outcome. Your decisions on suggestions write lessons back. The next session is handed them, with a receipt that shows what it got.

Lessons

A lesson is one or two sentences, in the imperative, naming the file or function, written by the reviewer that found the mechanism. It exists only when something verifiable happened. The sources that can make one:

  • a finding the sandbox proved (a test failed, then passed with the fix);
  • a fix PR you merged;
  • a read that two sessions each proved dispensable, or a tool call the same correction fixed on two sessions (load-bearing and tool-path lessons);
  • the same uncorrected tool failure on two sessions, or the same verify command passed on three (mined; recurrence is the proof).

A review verdict, a fork that diverged, a rejected finding, a single corrected call: none of these make a lesson. Reviewer consensus never does.

A lesson is scoped to the repository it was born in. It widens to the account in exactly one way: a proven finding or a merged fix from a second repository of the same account matches it. It expires 30 days after its last confirmation; a later proven finding that names the same code confirms it instead of duplicating it and pushes the expiry out. There is no cross-tenant recall.

Source: packages/recall/cards/recall.input.json · packages/recall/cards/recall.output.json

Write-back from your decisions

When a pull request gets a new head or closes, the door reads every suggestion it posted there and decides what you did with it:

stateread asthen
appliedthe replacement is at the suggestion's place at the new head (GitHub's Apply, or the same fix typed by hand)accepted: a repo-scope lesson entry is created or confirmed
dismisseda maintainer replied refusing it (not a bug, won't fix, taste, duplicate, superseded, already fixed, other), or the PR merged with it unappliedsuppressed: the entry is demoted with your words as the reason (first 200 characters); it is never injected again
abandonedthe PR closed without merging, or the place could not be located at the merge headnothing: says nothing about the finding
openthe PR is open and you have not decidedobserved again on the next event

Only a maintainer's reply counts (owner, member, collaborator; never a bot). A merged fix PR is accepted; a fix PR closed with a typed refusal is dismissed. A proven finding writes back as accepted on its own.

One entry per mechanism per repository, lesson/<lens-title slug>-<hash>: a second acceptance of the same finding appends a receipt (which seat, under which guidance, on which PR) to the same entry rather than a duplicate. A demoted entry is never lifted by a later acceptance; only a person editing the store changes it. The entry is active, and so injectable, only when it carries an accepted receipt and the accepting seat’s lab. The write-back calls no model and never widens a decision beyond the repository it was made on.

Source: packages/github/cards/acceptance.input.json · packages/continual/cards/write-back.input.json · packages/continual/cards/store.json · packages/calibration/cards/suggestion-outcome.input.json

The review’s own memory

A review is many calls: seats × shards × lenses. The session-memory package records each call’s result with no model call and hands it to every later call of the same review, after the shard text so the shared header stays a cache prefix:

  • tool paths: a command that passed after a related command failed, errored or timed out (PYTHONPATH=src pytest found on shard 1 reaches shard 2 and every other seat);
  • hypotheses: refuted or confirmed, with their evidence ids;
  • findings: what one seat reported, for the other seats and lenses;
  • cross-session facts: what the batch’s other sessions taught (contradictions, repeated mistakes, decisions).

At the end of the review these persist: an executed tool path as an active memory entry for 90 days; hypotheses, findings and cross-session facts as candidates for 30 days. The next review of the repository is handed them as Recalled from earlier sessions: lines with the session, seat and commit, and the ledger counts a hit when a recalled subject came up again. Stored and recalled entries have no count cap. Each call receives at most 12,000 characters of memory, ordered by relevance to its files, then tool paths, then recency. The separate cross-session context block is bounded at 24,000 characters. Both blocks count omitted entries; the full record keeps them.

Source: packages/session-memory/cards/policy.json · packages/session-memory/cards/session-memory.input.json

What is injected into your agent

Lessons are the only imperative lines your agent receives. Everything else it is handed is a cited fact. There are four moments:

momentwhat
Session start (the hook hosts: Claude Code, Codex, Cursor; the MCP preamble)GET /v1/brief for the checkout: LESSONS (the repository's active lessons, newest confirmation first, up to 8), SWEPT SINCE YOUR LAST SESSION HERE (the sweep lines nobody has seen), YOUR FILES (who edited each modified file in the last 14 days and what was proven or reverted there), NOTES, CORRECTED BEFORE (a failed call an earlier session then fixed; the words a human used to ask again), and a one-sentence CONTRACT asking the agent to use parallax_ask before changing a system it can name and to credit a lesson it applied. Cut at 6,000 characters because Claude Code truncates a hook's context at 8,000.
Every request through the proxyA short block appended to the system message: "Parallax recall for this repo (N lessons, delete at GET /v1/recall)". A lesson that names a file is injected only when the request mentions that file; one that names none is repository-wide. File-relevant first, then repository, then account scope.
When the agent is mechanically uncertainThe PostToolUse hook detects a search repeated for the same identifier, an edit that missed, an edit to a file the session never read, or a test that failed twice on the same file, and asks GET /v1/context for that file or symbol: the code-graph slice, the lessons that name it, what was proven and reverted there, the notes that cite it. Once per subject per session.
Prime AgentPrime has no hook. The capture skill's start returns recall for the session: the repository's execution-verified tool paths, labelled [tool path], each with its session, seat and commit.

Each person under an account carries one preference card: recording full | incognito | off, surfacing 0 (nothing volunteered; the tools still answer) to 3 (the brief and the context pushes), and lesson_cap 1–20, the most lessons the brief and the proxy inject for that person. Read and set it at GET|PUT /v1/persons/preference.

Source: packages/brief/cards/brief.input.json · packages/recall/cards/recall.input.json · packages/persons/cards/preference.json · scripts/session-start.ts · packages/prime-capture/cards/prime-capture.input.json

Recall receipts: how to see it

Every lesson carries its provenance: the session and finding that made it, each confirmation, and when it expires. Every injection is recorded as a set.

terminal
# every lesson on the account, with sources, confirmations and expires_at
curl -s -H "authorization: Bearer $PARALLAX_TOKEN" "$PARALLAX_URL/v1/recall"

# what the next session in this repository is handed
curl -s -H "authorization: Bearer $PARALLAX_TOKEN" "$PARALLAX_URL/v1/recall/active?repo=$PWD"

# the brief as the hook sees it
curl -s -H "authorization: Bearer $PARALLAX_TOKEN" "$PARALLAX_URL/v1/brief?repo=$PWD"

# the review ledger with the Brain: lessons per repository and what each review was handed
curl -s -H "authorization: Bearer $PARALLAX_TOKEN" "$PARALLAX_URL/v1/review-ledger?brain=true"

On the door, each injection appends one line to <scope dir>/injections.jsonl in the continual store: { at_ms, session_id, surface: review | recall | brief | context, set_sha256, entries, chars }, and logs [parallax continual] <session> -> <surface> N entries set <sha> …. The set hash is how a later outcome is joined to what the session was handed. The hook’s brief file also records the provenance of every lesson handed (lessonsHanded: id, lens, kind, seat, sessions), and each review writes session-memory.jsonl with what it learned, recalled and hit; packages/session-memory/scripts/show.ts prints it.

To remove a lesson: DELETE /v1/recall/:id. It is gone and never re-created from the same source. Deleting a session with DELETE /v1/sessions/:id also deletes the lessons whose only source it was. A dismissed suggestion’s suppression lives in the store entry’s receipts (Control says what is kept for how long).

Source: packages/continual/cards/write-back.output.json · packages/ledger/cards/ledger.input.json · packages/server/cards/server.input.json · packages/session-memory/cards/session-memory.output.json