Give your AI agent memory that lasts — and see the cloud tokens it never had to spend. Persistent sessions, knowledge graphs, offline tool-routing, and an auditable savings meter. Fully local and free.
Prism Coder is an that gives Claude, Cursor, and other AI tools long-term memory that survives across sessions. It ships with the open-weight model fleet (2B–27B) for fast, offline tool-routing — no cloud required. And it keeps score: every call served locally is metered, so shows the token volume that never reached your cloud model — .
Persistent session memory for AI coding agents — local-first, with on-device inference, associative recall, and drift detection. Works with Claude Code, Cursor, and Codex.
No account needed. No API keys. Runs on your machine.
A paid subscription adds cloud sync, higher model tiers, and team features through the Synalux portal.
What Prism gives you
Session memory that survives restarts — resume projects with handoff notes,
recent work, open TODOs, and configurable quick, standard, or deep context.
Local-first inference — bounded work is routed through local Ollama models
first, with automatic 2B/4B/9B/27B selection based on installed models,
available RAM, context fit, and subscription entitlements.
A savings meter you can audit — prism savings (or the local_savings
tool from any host) reports the token volume local serving kept off your
cloud model: headline, local share, per-model breakdown. It reports tokens,
never an invented dollar figure, and prints its assumptions and known
undercounts inline — a number you can check, not marketing.
Route-output enforcement — route mode returns only well-formed calls to
tools the host actually advertised. Standard and higher plans can add
authenticated deterministic correction; route_guard: "local" disables that
correction only. cloud_fallback: false forbids cloud inference fallback and
verify: false (with no evidence) disables the grounding verifier. With all
three off, no request carries your prompt, draft or evidence; the per-call
entitlement check and telemetry still contact the portal and carry neither.
One setup for every agent — prism connect configures Claude Code,
Claude Desktop, Cursor, Gemini CLI, and Codex while preserving unrelated
settings.
Subscription-aware skills — entitled skills are synchronized before the
host launches, with safe upgrades, downgrades, conflict preservation, and
offline last-good recovery.
Hook-free startup — MCP metadata and native instructions request Prism's
startup context without requiring lifecycle hooks or a Prism-owned launcher.
Where a host offers hooks (Claude Code, Codex), prism connect adds two
small ones on top: mid-session prompt routing, and a post-compaction
re-injection of the protected-floor digest.
Prompt-triggered Factory — enabled by default for suitable bounded
implementation requests with explicit files, an allowed write list, and a
verification command. The host starts and monitors the recommended pipeline;
BCBA requests stay with the host. A dashboard toggle or
PRISM_DARK_FACTORY_ENABLED=false disables Factory after an MCP restart.
Try the three-test filename fix.
Safe escalation and observability — inference outcomes are explicit,
reserved text remains fail-closed (clinical images are processed locally,
never sent to the cloud), and local/cloud usage is recorded for
review.
Explicit on-device oMLX drafts
prism_infer keeps Ollama's four-tier routing by default. For an explicitly
selected text-only code or advisory reviewer draft, pass local_backend: "omlx",
mode: "code", and optionally local_model with the exact advertised model ID.
This path authenticates /v1/models before classification or any Ollama unload;
an unavailable, unauthenticated, or mismatched model refuses without substitution.
It reads OMLX_API_KEY or the local ~/.omlx/settings.json key, and model/context
settings from ~/.omlx/model_settings.json; OMLX_MODEL and a loopback-only
OMLX_BASE_URL can select local configuration. Redirects are refused.
Requires an oMLX build with Prism's control routes: the
prism-v0.7.1rc1 branch of dcostenco/omlx, upstream oMLX
0.7.1rc1 plus those routes (install and settings). With stock
oMLX every call is refused. Generation runs as an owned
job through those routes, so a timeout or cancel is reported only once the
server confirms the request stopped. An unconfirmed stop refuses later calls
(omlx_stop_unproved, omlx_provider_busy).
Before classification, Prism unloads every model Ollama has loaded
(keep_alive: 0; the weights stay on disk and reload on the next Ollama call)
and waits up to 10 seconds for Ollama to report none. A failed unload, a model
that does not drain, or one loading meanwhile refuses the call; a newcomer is
never unloaded. Ollama must be reachable for this step. An OS-owned loopback
lease on port 19438 excludes other candidate MCP processes; ordinary calls within
one process share this lease. A busy lease refuses (omlx_resource_busy) before
classification or unloading, and process exit releases it without lock-file
cleanup. In-process inference and classification wait while an oMLX call owns
the device. Unknown Ollama state, newly loaded Ollama weights, or available
memory below a 2 GiB reserve aborts/withholds the generation. Model caches and
daemons remain in place. Legacy/unmodified MCP processes do not honor the lease;
their contention is observed and rejected by the watcher.
Safety screen. The classifier on this path is the public
dcostenco/prism-coder-9b-mlx-8bit, installed under the name
prism-coder-9b-mlx-8bit in oMLX's model folder (about 9.2 GB while loaded).
Layer 1's rules only refuse here; the classifier reads everything else, and a
prompt over 4,000 characters is read whole in 3,600-character windows (the most
severe verdict stands), never as an excerpt. A classifier failure, an unreadable
answer, or a missing classifier refuses the call; there is no keyword or Ollama
fallback. Each classifier read is bounded by 90 seconds and by the call's
remaining timeout_ms, so a classifier that macOS paged out during a long idle
is waited for rather than refused, and an oversize prompt read in windows
cannot outlast the call budget; the first unrecoverable read ends the
classification.
Configured oMLX sampling and reasoning are preserved unless temperature or
think is explicit, including through repairs. Generic thinking-disable retries
are disabled for oMLX, so a model with no thinking budget in oMLX's model
settings can spend its whole answer reasoning and is refused think_only: give
it a budget there, or pass think: false. The default 300-second budget bounds
oMLX generation, repairs, and history answer checks; timeout_ms may override it
up to 900 seconds. Context sizing uses conservative UTF-8 bytes and the
configured window.
The same entitlement, reserved-content, history, quality, output-safety, and
verification policies apply. Explicit oMLX never falls back to Ollama/cloud
inference. cloud_fallback: false, verify: false, and route_guard: "local"
keep content-bearing cloud channels disabled for a local draft. Result metadata
reports backend: "omlx", the selected model, tokens, and gate_outcome.
The MCP envelope carries this public metadata in structuredContent alongside
the existing human header/output text; next_step remains available in both.
Runtime authentication and internal verifier traces are excluded.
A draft is advisory and requires independent host review; it is not final sign-off.
Get started
Memory search automatically applies ACT-R ranking: relevance plus recency,
frequency and memory associations. No upvote or prompt instruction is required.
To opt out, use Account & Settings → Preferences → Automatic Memory Ranking
(ACT-R), then restart your AI client. PRISM_ACTR_ENABLED=false also disables
it. This ranking is separate from the neural graph's stored importance filter.
Use prism connect --dry-run to preview changes, prism connect --all to
configure every detected host, or prism connect --refresh to reconcile
Prism-managed entries after an upgrade. Restart the host after connecting.
prism dashboard opens the current local Mind Palace without a Synalux login.
Prism works locally without an account, API key, or cloud subscription. Add a
Synalux subscription when you want cloud memory, paid-tier skills, or team
features.
To check your plan, open ⚙ Account & Settings → Account in the dashboard.
Free users see Start 14-day trial; paid users see Manage subscription.
During a trial, the same panel shows the paid tier and exact end date. No card
is required to start. Add payment details before the end date to continue; if
you do not, the subscription cancels and local Prism Free remains available.
You can also compare plans directly at synalux.ai/pricing#prism-plans.
After a few sessions, ask what it's been worth:
prism savings --period month
💾 Local serving — LAST 30 DAYS
~510K tokens kept off your cloud model
53 call(s) served locally of 58 routed (91%)
Your numbers will differ — that's the point: it reports what your machine
actually served, not a projection. Full report anatomy and the honesty rules
behind it are in the
local_savings section.
Install as a plugin
Prism also ships as a plugin, which registers the MCP server and the startup
skill for you.
Both hosts install straight from this repository. There is nothing to host and
no server to run: the catalogue is the .claude-plugin/marketplace.json file
committed here, and your client clones it from GitHub.
Claude Code:
claude plugin marketplace add dcostenco/prism-coder
claude plugin install prism-coder@prism
The plugin registers prism-mcp via npx -y prism-mcp-server. If you already
configured Prism by hand — prism connect writes an mcp_servers.prism-mcp
entry — you have that server twice under one key. Install the plugin or
run prism connect, not both.
What prism connect changes about host subagents
connect steers bounded work to prism_infer on your machine rather than to
host-spawned agents. What it writes differs per host, and it does not disable
subagents everywhere — Claude Code keeps them and is pointed at an economy
model instead. Prism's local workers stay available over MCP in every case.
Host
Setting written
Effect
Claude Code
env.CLAUDE_CODE_SUBAGENT_MODEL = "sonnet" in ~/.claude/settings.json
Subagents stay enabled, pinned to an economy model. Fan-out is discouraged by policy text, not by config
Gemini CLI
experimental.enableAgents = false in ~/.gemini/settings.json
Subagents off. Gemini exposes one boolean, so that is all there is to set
Codex
features.multi_agent = false in $CODEX_HOME/config.toml (default ~/.codex), plus a bounded fallback: 2 threads, depth 1, cheap subagent model, 900s cap
Subagents off, with a bounded profile underneath so a deliberate re-enable lands somewhere sane
Two things worth knowing:
experimental is Gemini's namespace, not ours. Prism is not enabling
anything experimental — it writes false to a flag Gemini already defines at
that path. Writing anywhere else would have no effect.
That namespace is by definition temporary. If Gemini promotes
enableAgents out of experimental, Prism keeps writing the old path, Gemini
reads the new one, and host subagents quietly turn back on. Nothing errors and
the settings file still looks correct. If you see host subagents running while
enableAgents reads false, check whether the key has moved before assuming
connect failed to write it.
Both writes are idempotent in the sense that a host already configured this way
is left untouched — but they are re-applied on every prism connect run,
not only on --refresh. If you deliberately re-enable host subagents, the next
connect will turn them off again. Keep them on by not re-running connect,
or by re-enabling after each run.
What's New in v20.22.1
Why it matters: on explicit oMLX, a long prompt could keep the device busy
for minutes while being classified, and timeout_ms did not limit it.
The call budget now covers classification.timeout_ms (default 300 s)
starts before the safety screen, and each classifier read is bounded by the
remaining budget as well as its own 90 s.
A failed read ends the classification. An oversize prompt is read in
3,600-character windows; a read that fails already means refusal on this
path, so the remaining windows are no longer read. Before, a stalled server
could cost about four minutes per window.
Tests: the owned-job marker tests pin the size limit and the
non-blocking open directly.
What's New in v20.22.0
Why it matters: on Apple Silicon, prism_infer can now draft code on an
oMLX server instead of Ollama, opt-in per call, behind its own safety screen.
Separately, Layer 1 now marks two more kinds of auth request reserved, on every
path.
Opt-in oMLX backend:local_backend: "omlx" with mode: "code", text
only. Nothing changes for calls that do not ask for it. It requires the
oMLX build with Prism's control routes, published as the
prism-v0.7.1rc1 branch of dcostenco/omlx
(install and settings); with stock oMLX every call is refused.
Its own safety screen: the 9b classifier on the same oMLX server reads
every request; rules only refuse. In our tests, of 327 labelled sensitive
requests, the 9b alone let 2 run locally, against 19 for the 4b classifier
on Ollama; two rules written after reviewing those rows bring this path to
0, so 0 is not an out-of-sample figure. Of 294 routine requests, 2 were
escalated (27 on Ollama). Of 135 adversarial probes, 3 ran locally, all one
shape (a documentation field).
Speed and cost: a classifier read took about 0.37 s at the 95th
percentile on an idle machine and up to 0.65 s under load. The first read
after a long idle took 14.5 s, because macOS had paged the classifier out,
so Prism waits up to 90 s for it instead of refusing. The classifier holds
about 9.2 GB while loaded (9.7 GB peak).
Fails closed: a classifier failure, an unreadable answer or a missing
model refuses the call; it never falls back to a keyword check or to
Ollama. A long prompt is read whole, in windows, not as an excerpt.
Frees memory first: Ollama's loaded models are unloaded before the call
(they reload on the next Ollama call), so the two runtimes do not hold large
models at once.
Layer 1, every path: a request that decides whether signed-out,
anonymous or guest users may reach a route, page or endpoint (granting or
blocking it), makes one public, or gives them admin rights is marked
reserved by rule, and so is code that exchanges an authorization code for
tokens. Measured on the 327 sensitive requests on
the default Ollama path: 18 now run locally, against 19 before; routine
escalations are unchanged (27 of 294).
What's New in v20.21.27
Why it matters: a script that feeds Prism Browser through a pipe can
now pause between blocks of commands. Before, commands that had already
arrived waited for the next write, and never ran if the 600 s idle timeout
came first, so a script that checked a result before sending more stalled
and then failed.
Every piped command runs when it arrives. The reader waited on
select() for new pipe data while readline() had already buffered the
commands sent so far. It now reads the descriptor itself and decodes it as
the text stream did (its encoding, universal newlines). Measured with two
commands written together and a third written only after the reader hands
over the second: the second came out only with the third before, and
before the third is written now.
Unchanged: the idle timeout, \ line continuation (CRLF endings
included), comment lines, and streams select() cannot watch, now read
blocking. At the idle timeout, a command still being written is dropped,
never run cut short.
What's New in v20.21.26
Why it matters: routine wording no longer lets a mixed request skip
Layer 1, the safety screen that decides whether a request may run on your
device. A BCBA who asks in one message for an operational
definition and how many mL of a drug to give, or a developer who asks for a
code review and then authentication code, now has that request screened by
Layer 1's rules and, unless the request or conversation is already marked
reserved, a classifier read. Before, it could be answered by a local model
with no classifier read.
Rules no longer clear requests. Before, one routine clause let Layer 1's
rules clear the whole request, so it skipped the classifier. "Write an
operational definition for tantrums and tell me how many mL of Benadryl to
give at bedtime" was answered locally with no classifier read, and so was
"review the dashboard component for hook order and then write the JWT
validation middleware". Now rules can only mark a request reserved. The
routine shortcut is gone for a single prompt and for the current prompt of a
follow-up; the prompt's classifier read is skipped only if the request or
conversation is already marked reserved. A long prompt that reaches the
classifier is read as excerpts, as before.
What happens to a flagged request. A text request that a rule marks
reserved, or that the classifier flags, goes to a stronger cloud model when
your plan includes cloud and the call does not pass cloud_fallback: false.
Otherwise it is refused, and the refusal says why. Requests the classifier
clears remain eligible to run locally, so routine drafting (operational
definitions, data sheets, antecedent strategies) and routine code work still
run on your device when the local model can answer.
Seclusion by another name. Placement phrases such as "put him in the
quiet room until he calms down" (also isolation, time-out, padded and
calm-down rooms) are now marked reserved by rule. This catches placement
requests of that shape (him, her, them, or the client, student or child
placed into the room) that never use the word "seclusion". Other wording,
and other mentions of these rooms, are left to the classifier.
Measured: of 46 mixed requests built to test this bypass, which should
never be answered locally, 41 were cleared to run locally before this
release and 9 after: 32 fewer sensitive requests reaching a local model. Of
294 routine requests, 2 more than before are escalated (or refused, without
cloud).
Limits, unchanged in this release. Keep them in mind when deciding
whether a local answer needs your review:
The classifier can miss a request, and a missed request still runs
locally. The 9 above are such misses.
Some classifier failures fall back to a keyword check, and text that
passes it can still run locally.
A request with images is processed on this device even when flagged, and
is never sent to the cloud.
Cost: requests that used the shortcut now need a classifier read, unless
screening has already marked them reserved. That added check is the price of
closing the bypass; in our tests the read took about 0.3 s at the 95th
percentile.
What's New in v20.21.25
Semantic memory search now automatically applies ACT-R ranking, combining
relevance with recency, frequency and associations. Account & Settings →
Preferences → Automatic Memory Ranking (ACT-R) lets you opt out after an AI
client restart; an explicit environment value takes precedence.
Synalux Cloud uses authenticated, owner-scoped access-history and candidate-link
APIs. Cloud deployment requires the matching Portal history migration. Stored
importance thresholds remain separate, and HRR drift detection remains independent.
What's New in v20.21.24
Synalux cloud preserves initial importance and handles votes, graduated
insights, and stale-score decay through the authenticated Portal API.
Voting rejects inactive or inaccessible records; decay preserves archived
history. Existing scores remain unchanged.
Graph importance thresholds use stored scores. Automatic retrieval ranking
and access tracking do not automatically turn ordinary memories into high-score rules.
What's New in v20.21.23
Factory routes suitable bounded implementation prompts and executes only the
allowed file actions, with independent verification and explicit lifecycle results.
Paid pipeline creation, updates, aborts, and verification records use the
authenticated Portal API. Startup waits for paid storage initialization before
reporting Factory readiness.
The default-enabled toggle distinguishes the saved setting from the active
MCP setting and shows when a restart is required.
What's New in v20.21.22
Factory pipeline lists for cloud accounts use the authenticated Portal API,
including exact project and status filters, without direct database credentials.
Invalid, incomplete, or oversized reads show an unavailable state. A valid empty
list remains distinct from a failed read.
This release covers pipeline lists. Cloud pipeline creation, controls, and
execution still need separate validation.
What's New in v20.21.21
Prism Dashboard now reports unavailable analytics and factory reads clearly,
prevents stale project results, and keeps graph filters and counts in sync.
Project analytics can be read through the authenticated Portal API with
validated 14-day activity data.
What's New in v20.21.20
Fixed: a session_save_ledger call refused with context_not_loaded, or the
greeting-only reply that writes nothing, restarted the hourly drift reminder.
A ledger save restarts it now only when it writes an entry.
A written ledger entry's reply also asks for the handoff when the checkpoint
ends a unit of work.
A ledger save skipped as a duplicate of one saved in the last 5 minutes now
says nothing new was written, instead of "saved".
Fixed: with Supabase storage, a handoff whose save failed was reported as
updated. It is now an error the agent can see and retry.
What's New in v20.21.19
Prism Browser emulates phones and tablets. --device iphone-17, or one of
five other measured iPhones and iPads, turns on touch CSS, the pixel ratio,
and the iPhone safe area, so a layout that only breaks on the phone can be
caught in a test. --touch, --device-scale-factor, and --safe-area set
each part on its own.
What's New in v20.21.18
Fixed: when a save was refused with context_not_loaded, the instructions
Prism installs for Claude Code, Codex and Gemini CLI forbade the one call
that recovers. The refusal now prints that call, session_load_context
with the same project and conversation_id, and the installed instructions
allow it. First-turn startup is unchanged.
What's New in v20.21.17
Fixed: the on-device screen refused some ordinary coding requests. With a
Synalux account (free included), it now reads each request through a policy
that Synalux serves, pinned by its SHA-256. Without an account, or with
images attached, the screen is unchanged.
prism_infer route mode: set allow_parallel_calls to keep a reply that
calls several of the tools you offered in allowed_tools.
What's New in v20.21.16
Conversations: checked on your device, and free with an account
A local answer to a conversation is checked on your device before it is
served. If the check fails or cannot run, the answer goes to the cloud when
your plan and settings allow it, and is withheld otherwise.
On Pro and Team, a local answer that passes is also confirmed by Synalux, on
a copy pseudonymized on your device; the mapping stays on your device. With
an image attached, or with the cloud off, the checked local answer is served.
When the on-device screen's 4b is unsure about a conversation, the 9b reads
it again before the conversation is refused or sent to the cloud.
Everything local is free with no account and no cap on the local model size.
A free Synalux account adds multi-turn prism_infer and 20 cloud answers a
day. Pro ($15/month) and Team ($20/seat/month) are Prism's own plans.
Optional You.com web search: set YDC_API_KEY to enable
youcom_web_search (contributed by @mouse-value-add in #227).
Fixed: the 2b and 4b no longer answer Prism's own requests as a tool router.
A system prompt built into those models had turned some answers into tool
calls and made the on-device screen refuse some ordinary requests.
What's New in v20.21.15
Follow-ups: see what runs locally, and a stricter screen when the classifier is down
local_savings (and prism savings) shows a line for follow-ups, calls that
carried your conversation. It covers how many the local model answered (and
how many of those the 9b answered), how many the on-device screen refused and
at which stage, how many your plan's multi-turn limits refused, and how many
went to the cloud.
A short chat answer ("16", "Yes") counts as an answer. Before, the quality
gate treated it as empty, and a paid plan re-asked the cloud.
When the on-device classifier fails every read on a follow-up, the follow-up
is no longer answered on a keyword check alone. It goes to the cloud if your
plan allows it, and is refused otherwise.
What's New in v20.21.14
Skills load when they help, and you can see why they loaded
Background task notifications, reports from other agents and continuation
summaries no longer load skills in the middle of a task, so a word inside an
agent's report cannot pull in unrelated rules.
Pasting Prism's startup output into a prompt no longer loads skills that
happen to share a word with it.
Tasks that say they need host tools or reserved judgment stay with the host
instead of failing on the local worker.
Every routed-skills header ends with the routing table version (for example
"Routing table v41."), so a past skill load can be checked against the exact
rules that chose it.
Skills with their own triggers now load even when their file uses Windows
line endings or mentions prompt_triggers: in its description; before, they
were delivered but silently never loaded.
What's New in v20.21.13
Paid plans and trials are clear in Account & Settings
Free users can open the Prism plan comparison and start a 14-day trial.
Trial users see their paid tier, exact end date, and the action to add payment
details before automatic cancellation.
Active and payment-recovery states lead to the correct hosted billing action;
an unavailable verification is labeled instead of being presented as paid.
Local Prism Free remains available without an account or subscription.
What's New in v20.21.12
Multiple MCP hosts keep a working dashboard link
Each running Prism host now registers its local dashboard independently.
prism dashboard and the startup message verify the newest candidates and
fall back to an older live dashboard when a newer host stops.
Instance cleanup cannot remove another host's registration, and the open
message preserves the linked account and plan description.
What's New in v20.21.11
Linked accounts persist across dashboard refreshes
A host process with an obsolete launch credential now recovers from the
newer account saved by the dashboard after the obsolete credential is
rejected.
Valid host credentials remain authoritative; sign-out, concurrent account
changes, network failures, and server failures do not trigger an unsafe
credential switch.
prism dashboard opens the active local dashboard without relabeling a
linked Standard, Advanced, or Enterprise account as Free.
What's New in v20.21.10
Signed-out Free dashboards keep working locally
Signing out now switches Project View, project details, and graph reads to
local SQLite without requiring an account, configuration edit, or restart.
The saved Synalux backend preference remains ready for the next sign-in;
accidental missing cloud credentials still fail closed.
Latest Activity uses the newest durable session when it is newer than the
saved handoff. Recent Sessions are newest first, and saved handoff versions
remain available as restore points.
What's New in v20.21.9
Prism Free opens without a Synalux account
Run prism dashboard to open the current local Mind Palace. No sign-in,
account-link code, API key, paid plan, or Free-plan redemption is required.
A bare local dashboard address now gives the exact local-open command instead
of rendering a broken account state.
Account & Settings shows Prism Free as active. Synalux linking remains an
optional action for cloud sync, billing, and paid features.
Local access stays protected without printing its browser capability into
startup output, and unsafe state paths or redirected identity probes fail
closed.
What's New in v20.21.8
Dashboard graphs use the authenticated Portal
The selected cloud project now shows its real session nodes and stored links
instead of collapsing to a keyword-only project bubble.
Synthesize Edges uses the authenticated Synalux Portal embedding contract;
the Prism dashboard process does not need a Google or Gemini API key.
Existing vectors and links are reused on repeat runs, synthesis fan-out is
bounded, and Portal failures are shown rather than rendered as an empty graph.
Account & Settings now shows the current user, role, and Free, Standard,
Advanced, or Enterprise plan, with visible sign-in, upgrade, billing, and
sign-out actions.
A selected paid plan survives the Portal sign-in round trip, live and test
Stripe catalogs resolve every paid tier, and localized checkout never reuses
a USD Price for another currency.
What's New in v20.18.1
Task skills survive compaction and update in place
Prompt-routed task skills now return after compaction. The hook restores
the three most recently active task skills alongside the protected-floor
digest, so a short follow-up such as continue keeps the workflow and visual
verification rules that governed the work before context was compacted.
A completed managed-skill sync refreshes active task rules on the next
prompt. The hook compares the materialized generation on disk with its
per-session state, re-authorizes every restored name against the current
manifest, and injects the current bodies. A downgrade clears stale paid task
state; Prism-managed directories cannot use the user-owned local-skill
exception.
User-owned local skills now route with their actual body. A local
SKILL.md remains usable while signed out, while an entitled platform body
takes precedence if both sources use the same name.
Codex hook context is anchored to the user's request. Routed rules tell
the model to execute the preceding user request with the rules applied,
avoiding the trailing developer-context placement being mistaken for a new
task. The anchor and all restored content share the 9,800-character limit.
Hook version 5 enforces its command version. A still-running host with a
trusted v4 command cannot execute the rewritten v5 script. After upgrading,
run prism connect --refresh --no-models; Codex must trust both new v5 hook
entries in /hooks. Restart the host if it has not reloaded the new hook
definitions. Once v5 is active, later skill-body generations refresh on the
next prompt without another host restart.
State names are validated and bounded before they become CLI arguments, and
the two-call refresh paths fit inside the host's 15-second hook timeout.
What's New in v20.18.0
The protected floor rides the bootstrap — and survives compaction
session_bootstrap now inlines a digest of the protected floor on
paid tiers at standard and deep depth: one inert line per rule, derived
from each skill's first paragraph (or its pinned digest:), plus its
section map, ~5.6K chars for the full floor. Small-context hosts such as
Codex were re-reading the sixteen SKILL.md files every session (median 8
re-reads / 36KB, worst 823 / 5.1MB in rollout logs) because the bootstrap
only named them. The digest is paid for on top of the context budget, so
the ledger/handoff share at every depth is byte-identical to before. Quick
depth stays names-only — the opt-out.
A second hook re-injects the digest after compaction.prism connect
registers the prism-route script on SessionStart matched to compact
(Claude Code and Codex); it runs prism floor-digest, which applies the
same tier and depth decisions as the bootstrap, and adds nothing on
startup/resume/clear. Hosts without hooks (Gemini, Cursor) still get the
digest on every bootstrap. Codex: UNVERIFIED against a live compaction.
The hook is registered and the script accepts the documented payload
spellings, but no Codex compaction has been observed end-to-end; on a
payload it does not recognise it re-injects nothing rather than something
wrong. If the digest comes from a generation whose skill files never
finished syncing, the re-injected block carries the same STALE warning the
bootstrap shows.
Codex trust is reported honestly after a hook rewrite. Approvals are
keyed by definition hash, so a rewritten hooks.json — this release adds
the SessionStart entry — voids prior trust: connect prints AWAITING TRUST
for both entries instead of a green ✓ for a hook Codex would silently skip,
and trust recorded for an older hook version is never mistaken for current.
A host config that no longer parses is left alone. If
~/.claude/settings.json or ~/.codex/hooks.json exists but is not valid
JSON, connect keeps it byte-identical, registers no hook there, and says so
— it no longer replaces the file with a minimal hooks-only one. The npm
postinstall notice says the same, instead of asking you to trust a Codex
hook it never registered.
Fixed: a symptom-routed skill whose closing frontmatter fence is its last
line was inlined with its YAML (triggers included) as if it were the rule.
Fixed: a digest line that crosses into a new section keeps that section's
heading in front of it — whatever opened the section (an H2, a mid-document
H1, an empty heading, a setext underline) — so "Delegate to" / "Do NOT
delegate" rules cannot read with the wrong polarity once joined. A skill
file on disk is used only when it digests: empty, cut off inside its
frontmatter, or frontmatter-only files fall back to the stored copy instead
of rendering YAML as the rule.
Fixed: on Windows, a Codex hook approval is recognised even though Codex
stores the path with escaped backslashes.
The publish gate now refuses release notes that run ahead of the package
version (CHANGELOG, README, translated READMEs) — reading the newest
version on the heading line, so a v20.17.3 – v20.18.0 range counts as
20.18.0, and surviving a typographic apostrophe or a BOM.
What's New in v20.17.3
A plugin install can no longer enable the prompt-routing hook. The
package's maintenance paths (npm postinstall, server startup) now only
refresh a hook that an explicit prism connect previously installed —
a prism MCP registration in host config no longer counts as consent.
First install of the hook happens through prism connect or not at all.
The Claude Code plugin launcher is fully deterministic. It runs the
exact pinned server version with npm lifecycle scripts disabled, and
the plugin now documents its security posture in plugins/prism/README.md.
What's New in v20.17.2
Pasted logs can no longer falsely activate skills. Symptom-triggered
routing now strips fenced blocks and routable skill-name mentions (including
inside compound identifiers like container/pod names) from the routing view
of a prompt, so quoting an agent log or a skill list doesn't load skills the
text merely mentions. Skills named by ordinary words keep routing normally.
Symptom-routed skills now arrive whole. Startup budgets deliver the full
rule text at every depth that fits; when a rule genuinely cannot fit, the
display says exactly how much is missing and how to load the rest, instead
of silently truncating.
Routing can no longer be silently disabled by one bad skill. Corrupt or
hostile trigger tables — wrong value shapes, patterns named after object
prototype properties — are skipped per entry instead of taking down all
prompt routing (or, in one case, the vault export) for the session.
What's New in v20.17.1
Fixes a broken CLI in 20.17.0 — a command-name collision made every
prism CLI invocation exit with a commander error at startup (the MCP
server was unaffected). The handoff-sync command is prism handoff …;
prism sync remains cross-backend data synchronization. If you installed
20.17.0, update.
Resume a session on any of your machines. With prism handoff enable (paid,
off by default), each session_save_handoff seals the handoff to all your
account's device keys and relays the CIPHERTEXT; another machine pulls with
sync_pull_handoff (or prism handoff pull <project>) and opens it locally.
The relay stores ciphertext only — X25519 + AES-256-GCM sealed
envelopes. No key that opens a handoff ever exists server-side. The channel
is deliberately separate from savings sync, which carries counters only.
TOFU device pinning surfaces a compromised relay: sealing to a key this
machine has never seen warns loudly, keyed on the client-derived recipient
id so a swapped key can't hide behind a familiar device name.
prism handoff status|devices to inspect; revoke a lost machine from the portal.
What's New in v20.16.0
See What Local Serving Saves You — Meterable, Auditable, Team-Wide
local_savings tool + prism savings CLI — the token volume local
serving kept off your cloud model: all time, trailing 30/7 days, or any
--days N window. Tokens, never an invented dollar figure, with the
assumptions and known undercounts printed inline.
Team roll-up (paid) — prism savings --sync-enable uploads per-day
counters only (never content; the payload is a closed field set the server
also enforces); prism savings --team shows the workspace-wide total with
per-member share. Off by default.
E2E sync foundation — sealed multi-recipient envelopes (X25519 +
HKDF-SHA256 + AES-256-GCM on node:crypto, no new dependency) and per-device
identities, adversarially reviewed: cross-machine session sync will ship on
a relay that only ever stores ciphertext.
Push-time public-leak guard — outgoing diffs AND commit messages are
scanned before anything leaves the machine.
What's New in v20.12.1
prism connect --refresh now converges every registration it owns, not
just the top-level one — directory-scoped entries could otherwise keep
launching an old build indefinitely.
prism update checks the installed package, not the CLI that happens to
be running, so it can no longer report "current" while the install is stale.
The opt-in scheduled updater can actually start — the LaunchAgent now
carries a PATH that includes node and npm.
What's New in v20.12.0
Prism now tells you when it's out of date. Session startup shows a
one-line update notice when a newer release exists — cache-backed, at most
one registry check per day, silent offline. PRISM_NO_UPDATE_CHECK=1
opts out.
Hands-free updates, if you want them.prism autoupdate enable sets up
a daily prism update --if-idle: it updates only the global npm package,
defers while any Prism server is running, and never touches host
configuration — that stays behind a visible prism connect.
What's New in v20.11.1
Saving memory never gets refused. The save path used to reject
session_save_ledger/save_handoff calls when its path-to-project
heuristic disagreed with the project you declared — and the registry the
heuristic trusted could contain junk from earlier auto-registration, so
legitimate sessions ended unsaved. Your declaration now always wins; the
disagreement is returned as an advisory warning, and auto-registration
only accepts real repository roots.
Screenshots are evidence again.prism browser captures on macOS were
silently upscaled to the size cap, so a screenshot no longer showed what
actually rendered. Only genuinely oversized captures are resized now, and
the cap no longer clips a standard 1920-wide viewport.
What's New in v20.10.0 – v20.11.0
Skill routing now works mid-session. New prompts are matched on-device
as the conversation moves — not just on turn one — and injected within each
host's real context limits (Claude Code caps hook output at 10k chars;
Codex truncates by default), with pointer-first delivery when a payload
can't fit inline.
prism connect is a converge command. It self-updates first, re-execs,
then reconciles MCP registration, skills, and hooks — no more
"fresh config, stale code" machines.
Scoped skills route on prompts too, and startup output survives hosts
that discard structured tool content.
What's New in v20.9.0 – v20.9.3
Your skills follow your account.skill_save stores a skill at the
scope you choose: this machine only (local, works offline and signed out),
your account (user — every machine you sign into receives it), or a
workspace (team — shared with members, admin-managed, optionally targeted
to specific people).
Trim the catalog you don't use.skill_manage can release platform
skills you never touch — freeing host skill-catalog budget — and restore
them any time, losslessly. Deleting a scoped skill archives its final
content locally first, so nothing is ever silently unrecoverable.
Delivery that queues instead of failing. Concurrent sessions no longer
starve skill sync on the local config store (WAL + busy-timeout) — a failure
that previously reported only "partial" where nobody could see it.
Withheld rules still bind. When the context budget can't inline a
skill's text, the manifest of withheld names now states that those skills
still govern the work and names every way to load them before completion
claims.
The budget the floor never spent. A long-standing accounting bug meant
no unprotected skill ever inlined at any normal context level — the
always-inlined protected floor was debiting the budget meant for everything
else. Task-matched skills (like the completion-evidence checklist) now
actually arrive.
What's New in v20.8.2
Skill delivery now admits failure instead of hiding it. A filesystem
permission edge case (a umask stripping the owner-execute bit) could leave
skill sync writing nothing while reporting itself current — measured at nine
days on a real machine. Broken managed directories are repaired in place,
every directory is created umask-proof, and the repair path refuses symlinks
via an O_NOFOLLOW descriptor.
A stale install tells you at startup. Prism now tracks the generation
that actually reached disk separately from the one the database accepted; if
they diverge, the startup banner says so in a warning placed where display
truncation cannot cut it. A successful sync clears it automatically.
What's New in v20.7 – v20.8.0
First run proves the memory instead of describing it — session_bootstrap
seeds one demo memory and shows it recalled from disk, so the save→recall
loop is felt in session 1. One-shot, contained in its own prism-demo
project, removable with one call.
Dashboard fixed — a quoting typo (shipped 2026-05-29) killed the inline
script at parse time, so every dashboard since rendered "Loading projects..."
forever. Fixed, and the ES5 lint now node --checks the built inline script
so an unparseable dashboard can never ship again.
Trusted Publishing — npm releases authenticate via GitHub OIDC. No stored
token to expire or leak, and every release carries a signed provenance
attestation — you
can verify the tarball you install was built from this repo by CI
(npm audit signatures).
TLS enforced for cloud sync — a remote http:// storage URL is upgraded
to https:// instead of silently sending session content in the clear.
Codex plugin collision + enabled-state detection — prism connect skips
its own registration only when a plugin actually provides prism-mcp
(cache present and enabled), preventing both duplicate and missing
servers.
Windows CI stabilized; registry/npm listings realigned and deduplicated.
What's New in v20.6.0
Delivery Is Not a Suggestion
An audit of a real incident (an agent wiped demo data after announcing the
wipe — with the ask-first rule committed, bundled, and absent from what any
agent actually received) found the protected floor had outgrown every delivery
budget: "unprotected" had quietly come to mean "never delivered".
ask-first and feature-preservation join the protected floor (14 → 16).
Protected skills are always inlined; these two now reach every session.
Sync conflicts are loud and named. Startup used to say "· 2 local
conflicts preserved" while safety skills sat months stale; it now names each
frozen skill and states how to resume updates.
--storage accepts auto and synalux — the CLI rejected its own
documented default and the production backend.
Disclosure: skill delivery informs; it does not gate. A live probe showed
a host agent still edit unverified source with the rule loaded. If your
threat model includes an agent acting against a loaded rule under task
pressure, pair this package with mechanical gates (hooks, permissions,
least-privilege roles). True of every prior release; stated from this one.
What's New in v20.5.3
Grounding Evidence Carries Its Age
Memory-grounded answers labelled their sources but never dated them, so a
two-year-old note and yesterday's reached the model identically. Nothing in the
evidence let it discount the stale one. Prompted by an external review naming
the right risk for local-first memory: the data stays local, but bad grounding
becomes permanent — storing everything on your machine removes the outside
pressure that would otherwise surface a stale note.
Evidence now reads:
[SOURCE 1: ledger:8286581d (recorded 2025-05-29, 431 days ago)]
The date already existed in storage and was being dropped at the snippet layer,
so this is plumbing rather than new data collection. Zone-less SQLite
timestamps are normalised to UTC — read as local, a ten-minute-old record
parsed hours into the future and its age was suppressed entirely, meaning the
feature silently did nothing on the freshest memories. An absent or unparseable
date renders as nothing rather than defaulting to now; defaulting would make
the oldest memories, the ones most likely to be stale, appear freshest.
tests/integration/grounding-staleness.test.ts runs the reviewer's own probe —
seed a deliberately outdated note beside a contradicting fresh one and assert
the model receives both, visibly dated. Anyone can run it.
Not solved, and not claimed: retrieval does not weight recency. A stale note
shown beside a fresh one is the easy case — the model sees both dates and can
weigh them. The hard case is a stale note retrieved alone, because ranking is
by keyword match and an old store returns old results; then the age label is the
only defence and there is no fresher record to compare against. Tracked as
TECH_DEBT.md #4.
What's New in v20.5.0 – v20.5.2
The First Message Never Leaves Your Machine
Symptom-triggered skills — the rules that fire on "can't see X", "no rows",
"the list is empty" — are meant to load on the turn an incident report arrives.
They never did: every host template called session_bootstrap with {}, so
there was no prompt to match against.
Fixing that raised the question of where matching happens. It now happens
locally. The 28 keyword rules are already public, so there was nothing a local
match could not compute, and callPortal() has no prompt parameter at all —
the guarantee is structural, not a promise. The portal request carries the
project and role only.
A matched rule now arrives as content, not as a name. Native hosts outside
the skill-file mirror had no way to read a rule they were only told about, so
the rule body is inlined into the startup display, bounded and sized against
the real per-project budget.
What's New in v20.4.0
An Explicitly Named Cloud Backend Fails Loud
Setting PRISM_STORAGE=synalux or =supabase with incomplete credentials used
to downgrade silently to local SQLite. The switch was logged to stderr, which
MCP hosts discard, so nothing surfaced it: sessions kept serving stale local
context while the cloud held newer history, and context_source read local
rather than any kind of warning. A session could run that way for weeks.
Naming a backend outright is a strong statement of intent, so it now throws —
naming the missing variables and the PRISM_STORAGE=local opt-out — instead of
quietly splitting your session history. auto is unchanged: it keeps its
documented synalux > supabase > local degradation, pinned by a test.
Upgrade note: if you explicitly set PRISM_STORAGE=synalux|supabase and
your credentials are incomplete, startup now fails with a named error instead
of silently using local data. That error is the fix — set the missing variable,
or choose PRISM_STORAGE=local deliberately. Default (auto) configs are
unaffected.
The throw is deliberately not treated as a recoverable startup fault: that path
exists for transient errors (rate limits, 5xx, DNS), which may degrade behind a
visible notice. A missing credential is a configuration fault and must not be
papered over.
Also: the skill block is now budgeted by default rather than only on request,
so a large skill payload cannot crowd out briefing and history.
What's New in v20.3.2
Web Scholar: SSRF Hardening
Security release. Web Scholar scrapes article URLs that come from
search-engine output, so the target is attacker-influenceable through SEO
poisoning — and because what it scrapes is written into the memory corpus and
passed to the configured LLM, a redirection to a local address meant reading an
internal service and sending the result onward.
The host guard matched string prefixes instead of parsing the address, and six
spellings of a local address got through: [::1] (URL.hostname keeps the
brackets), 127.0.0.2 (only .1 was enumerated, not all of 127.0.0.0/8),
0.0.0.0, [::ffff:127.0.0.1], localhost. (a trailing dot defeated every
suffix check at once), and [64:ff9b::7f00:1] (NAT64 embeds IPv4 in its low
bits). Host classification now parses addresses and also covers CGNAT,
benchmarking, multicast, reserved, and IPv6 unique-local and link-local ranges.
DNS rebinding is closed too. Every check read the URL string, so a hostname the
attacker controls passed all of them and could still resolve to 127.0.0.1.
Targets are now resolved first, every returned address is validated, and the
connection is pinned to those addresses so the name is never resolved a second
time — which also shuts the window between the check and the connect.
Scrape failures no longer vanish into a bare catch {}, a run is bounded by
PRISM_SCHOLAR_SCRAPE_BUDGET_MS (default 60s) instead of stalling on a raised
article count, and responses are capped at 8 MiB.
This is reachable only when scholar actually runs — scholar_research, or the
background loop under PRISM_SCHOLAR_ENABLED=true — and when the attacker also
controls DNS or a search result. Upgrade if you use Web Scholar.
What's New in v20.3.1
Prism Browser Reports Real Failures
prism browser could not fail a test. eval 1 === 2 returned status: ok
with exit code 0, a page serving HTTP 500 reported status: ok, and console
errors and uncaught page exceptions were discarded entirely. This release adds
assertions — assert-text, assert-visible, assert-count, assert-url,
assert-title, assert-eval, assert-no-page-errors — that return
status: failed and a non-zero exit. open now reports http_status and
fails on 400 or higher, screenshots are validated rather than assumed, and
eval returns native JSON with its type instead of a Python repr.
The fingerprint layer had never been applied: a wrong keyword argument made
the stealth library throw on every launch — 1,139 failures and 0 successes
since April — while the runner reported it as active. It is fixed, and a layer
that cannot be applied now fails loudly. The headless build no longer
advertises itself through navigator.userAgentData or the Sec-CH-UA header,
and a patch that corrupted Object.getOwnPropertyDescriptor on every page
under test has been removed. These remain best-effort test aids, not a
guarantee against bot detection.
--local-only now actually isolates: WebSocket, EventSource, WebRTC and
sendBeacon egress bypass request routing and were never blocked, and service
workers were allowed through. --cleanup was a no-op in the two modes agents
use. Site isolation, phishing detection and popup blocking are no longer
disabled by default, since these profiles hold live authenticated cookies.
New for test runs: --ephemeral-profile and --storage-state for hermetic
authenticated flows, pages/switch-page so OAuth popups are reachable,
--fail-fast, --fast, --trace/--video/--har, and
profiles --prune-older-than for profile maintenance.
What's New in v20.2.7
Session Saves Survive Agent Restarts
Prism now remembers that a conversation successfully loaded its project context
when the MCP server restarts or another Prism process handles the next request.
session_save_ledger and session_save_handoff no longer fail with a false
context_not_loaded error in that flow.
The recovery remains fail-closed: authorization is limited to the exact project
and conversation, expires with the existing context window, and stores no
plaintext conversation identifier. Cross-project, forged, malformed, expired,
or future-dated receipts are still rejected. The release also updates PostCSS
to the patched 8.5.23 release.
What's New in v20.3.0
Hybrid Memory Search (Portal Tier)
session_search_memory on the portal tier (Synalux-backed installs) now
fuses semantic similarity with exact-term lexical matching via weighted
reciprocal-rank fusion. Measured on blind probes against a real
8.5k-entry corpus: fused retrieval was never worse than semantic
alone at top-5, and exact identifiers — TPNs, function names, error
strings — now rescue queries that embedding similarity blurs. Results say how they were found — hybrid retrieval
headers, per-hit sem#/lex# arms — and a lexical-only rescue is labelled
exact-term match instead of pretending to a similarity score. Local
SQLite installs keep pure vector search; hybrid needs the portal's
lexical index.
What's New in v20.2.6
Safer Configuration Updates Across Every Agent
prism connect now reads Claude, Cursor, Gemini, and Codex configuration
through a single verified file snapshot, preventing another process from
swapping a file between Prism's safety check and its read. Supported symlinked
dotfiles still work, while dangling or planted symlinks fail loudly instead of
being followed or overwritten. This release also carries the patched
dependencies and cross-platform release checks introduced in v20.2.5.
Cloud fallback is now documented consistently as Gemini 3.6 Flash. Plan
ceilings govern automatic prism_infer routing; direct use of any downloaded
model through local Ollama remains free on every tier.
What's New in v20.2.4
Reliable Session Memory That Shows Work, Not Greetings
Greeting-only assistant replies are skipped before ledger writes. Existing
greeting rows are filtered at read time across native startup, MCP context, and
prism load --json, while entries containing decisions, TODOs, changed files,
or non-session events remain visible. Historical rows are not destructively
deleted. If Synalux has a transient startup failure, Prism displays one bounded
local last-good snapshot and clearly labels it; permanent authorization or
validation failures still fail loud, and later writes remain cloud-routed.
What's New in v20.2.2
One Local-First Workflow Across Every Agent
prism connect now installs one orchestration contract for Claude Code,
Claude Desktop, Cursor, Gemini CLI, and Codex. Bounded delegated work goes to
session_task_route and the local prism_infer worker first; routine work must
not create background host agents. Local workers can receive the active
project's dashboard-configured quick, standard, or deep memory and select a
RAM-safe 2B/4B/9B/27B model at call time. The router forwards complexity but
does not choose the model; prism_infer owns the final decision using memory
and context fit, installed models, live RAM, entitlements, and explicit caller
overrides.
Codex and Gemini native agent fan-out are disabled during connect. Codex keeps
a two-thread, one-level Terra/low fallback profile if the developer explicitly
re-enables native agents later. Claude Code keeps native agents as a last-resort
path but pins their model to Sonnet. Cursor and Claude Desktop do not expose a
supported global subagent-policy file, so they receive the identical workflow
through Prism's MCP server instructions. prism_infer safety boundaries and
the host's final verification responsibility are unchanged.
Subscription-Tier Skills Arrive Before the First Host Launch
prism connect now downloads the authoritative Synalux skill manifest and
materializes entitled packages in the native ~/.agents/skills directory
before the command exits. Codex therefore sees the current skillset on its
first launch instead of requiring a second restart. Prism rechecks the same
snapshot at MCP startup, session load, and every five minutes—skill delivery
never depends on a host lifecycle hook.
On the first user turn, Prism's native skill, MCP metadata, and managed host
instructions request one session_bootstrap({}) call. Prism then uses the
dashboard's developer name, Auto-Load Projects, and quick, standard, or deep
setting. The response stays focused on greeting and session state because tier
skills are already present in the host's native skill directory.
Hook-free MCP can provide and prioritize that ready-to-display block, but the
host model still owns the final assistant message and may summarize it. Prism
does not claim a deterministic verbatim greeting on third-party chat surfaces;
that would require a host lifecycle hook, launcher, extension, or Prism-owned
panel. Context loading itself remains complete even when a host shortens the
visible reply.
Free accounts receive only the public hook-free prism-startup package; the MCP
server still supplies a compact, non-proprietary safety and evidence contract.
Authenticated paid accounts receive the protected behavioral and engineering
packages plus the current subscribed routing set. The paid
evidence-first-protocol keeps ordinary coding lightweight: one correlated
reproduction is enough to begin an edit, while strict acceptance starts only
before a completion claim, push, or release and inspects only the exact artifacts
used as proof. Upgrades install newly entitled packages; verified downgrades
remove only Prism-owned packages while preserving local skills and locally
modified conflicts.
When upgrading an older Claude Code installation, prism connect removes only
the exact Prism-owned startup, skill-sync, handoff, and drift hook actions from
the legacy bootstrap. It also removes the recognized legacy Prism startup
sections from ~/CLAUDE.md, preserves every other instruction, and installs a
small ownership-marked native block that selects session_bootstrap({}) on the
first turn. User hooks, custom instruction sections, and near matches remain
untouched; native skills and server-side reminders preserve those Prism
features without depending on host lifecycle hooks. On Claude Code and Codex
connect additionally registers the prism-route script twice: on every prompt
(mid-session skill routing) and on SessionStart matched to compact only
(post-compaction protected-floor digest). Because hosts expose no native
session-end callback, handoff at shutdown is instruction-driven rather than a
guaranteed lifecycle event.
After Claude Code's native user registration succeeds, the same default or
--refresh command checks the nearest .mcp.json from the current directory
through the home directory. It removes only the exact legacy
prism-mcp entry { "command": "npx", "args": ["-y", "prism-mcp-server"] }
that would otherwise shadow the user registration. Custom Prism entries and
their additional fields, plus unrelated servers, are preserved; malformed
files fail loud without changes. --dry-run reports the recognized migration
without changing the file.
What's New in v20.2.1
Subscription-Aware Memory Storage
prism connect now carries an explicit PRISM_STORAGE=auto|local|synalux|supabase
into every managed host registration and rejects invalid values before changing a
config file. In auto, a portal-confirmed free tier uses local SQLite, while
Standard, Advanced, and Enterprise use Synalux cloud memory. If entitlement
resolution is unavailable, Prism fails closed instead of splitting history across
backends. Storage remains independent of local-first model routing.
What's New in v20.2.0
One Command Connects Every Supported Host
Install Prism globally and run prism connect. It detects Claude Code, Claude
Desktop on macOS, Windows, and Linux (beta), Cursor, Gemini CLI, and Codex, then safely registers the
server from the installed package. Existing custom entries are untouched;
--dry-run previews changes and --refresh updates only Prism-managed entries.
What's New in v20.1.0
Every Inference Outcome Is Now Observable
prism_infer gains a failure contract: pass escalation: "report" and every call returns a structured gate_outcome — success, degraded (gate-failed output served anyway, explicitly flagged), or refused (typed, with reason, instead of a thrown error). Degraded output can no longer serve silently.
Big Prompts Work Locally
Prompts over 4000 chars were blanket-refused when cloud was off. Now the full text gets a deterministic reserved-keyword scan plus a head+middle+tail excerpt classification — clean oversize prompts serve locally with a distinct UNCERTAIN_LENGTH audit marker. Clinical/reserved handling is unchanged (and its keyword floor got stronger).
No More Silent Truncation
Tier context limits now match the live Modelfiles (27b/9b are 4096-token models; 4b/2b are 32768 — the old table had it backwards). Tiers that can't hold your prompt are skipped with a visible ctx_insufficient reason; if nothing fits, you get the full prompt on cloud or a loud error — never an answer computed from a silently-clipped prompt.
Know Which Plan You're Actually Running Under
Entitlements carry a source field: portal (real), unconfigured (free by design), or fallback_free (portal unreachable — free limits ASSUMED). Pass strict_entitlements: true to fail loud instead of running degraded.
What's New in v20.0.8
verify_behavior Works Again
The verify_behavior tool crashed on every call (-32602 expected object, received string) — the handler returned a bare string instead of an MCP CallToolResult object. Fixed, with contract + fail-closed regression tests so the safety gate can never silently break again. If you're on 20.0.6/20.0.7, update.
From v20.0.7: Reserved-Content Safety, Skills Auth, Delegation Metrics
Reserved clinical content is now Claude-or-refuse (never served by a smaller model than the one that refused it), skill delivery gained a JWT auth fallback (paid-tier skills now reach machines using only PRISM_SYNALUX_API_KEY), and every prism_infer call is recorded in a persistent infer_metrics ledger. Full details in CHANGELOG.md.
The local-inference-first skill covers 15 hard-trigger categories (code gen, regex, format conversion, summarization, documentation, factual lookup, classification, shell commands, config gen, and more). Pasted code blocks now trigger delegation regardless of question phrasing. Measured delegation rate: 30-35% on engineering sessions, 40-60% on transform/content sessions. Rate depends on prompt mix, not the skill — the instruments now self-validate with nonDelegatedCount to prevent curated-set tautologies.
Think-Only Retry (v20.0.4)
Qwen 3.5 models (9B/27B) with thinking enabled could burn all tokens on <think> blocks and return empty content, causing a cascade to 4B. Now detects think-only responses and retries the same tier with thinking disabled — preserving model quality instead of falling to a smaller model.
What's New in v20.0.3
Layer 1 Cold-Model Resilience
(As shipped in an earlier release; the current contract is the header of src/utils/layer1.ts.) The reserved-category classifier retries once with a longer timeout on cold-model failure, then falls back to a deterministic keyword backstop; keyword-clean text is served locally. Over-length prompts (>4K chars) get the full-text keyword floor plus a head+middle+tail excerpt read and a distinct UNCERTAIN_LENGTH marker — prompt padding cannot force the ERROR branch. This eliminates the cold-start refusal problem without weakening the safety gate.
Keyword Backstop for Reserved Content
When the LLM classifier fails (timeout, injection, resource pressure), a deterministic regex floor catches reserved vocabulary (restraint, seclusion, self-harm, suicide, overdose, crisis de-escalation, etc.) including inflected and verb forms. Blocks prompt-padding and classifier-injection attacks on the ERROR path.
Single-Source Safety Text
The safety statement in the MCP server instructions field now imports from boundaries.ts — one source of truth instead of two hand-maintained copies. Boundaries version bumped to v3 with an explicit delivery decision documented in code.
Reserved-Category Safety Gate — All Tiers (v20.0.2)
The Layer 1 semantic classifier now runs for every user, not just paid tiers. Reserved clinical content is refused on free tier when cloud is unavailable — fail-closed.
Ledger Dedup (v20.0.2)
session_save_ledger deduplicates identical entries within a 5-minute window.
Evidence Script (v20.0.2)
scripts/generate-evidence.sh regenerates all 5 evidence files with built-in assertions. Run bash scripts/generate-evidence.sh to verify the full pipeline.
What's New in v20.0.0
License: AGPL-3.0 → Apache-2.0
Prism MCP is now Apache-2.0. The thin-client architecture means all proprietary value (skill resolution, tier gating, billing, cloud inference) lives server-side — the open client carries no moat to protect. Apache-2.0 removes the enterprise adoption friction that AGPL caused.
Thin Client Architecture
Skill routing, budget management, and content resolution have moved server-side to the Synalux portal. The MCP client is now a thin API caller — simpler, smaller, and portable across any host (Claude Code, Gemini, Cursor, autonomous scripts). Offline fallback reads the last successful response from local SQLite.
Clean-Room Voyage AI Adapter
The Voyage AI embedding adapter was independently reimplemented from the Voyage API docs to ensure 100% project-owned copyright. Default model updated to voyage-3.5. See PROVENANCE.md for details.
Server-Side Drift Detection
Session drift detection (GATE 5) no longer requires Claude Code hooks. The timer runs server-side per conversation, piggybacked on every MCP tool response. Works for any host.
CLA Requirement
External contributions now require signing the Individual CLA. The CLA check is merge-blocking on the main branch.
Quickstart
The free tier needs no account, no API key, and no cloud. Install Prism, then
register it with every supported MCP host already installed on your machine:
prism connect detects Claude Code, Claude Desktop (macOS/Windows/Linux), Cursor,
Gemini CLI, and Codex.
Use prism connect --all to target all five, --host <name> for one host, or
--dry-run to preview the files that would change. Existing prism and
prism-mcp entries are never overwritten by default. --refresh updates only
an entry previously created by Prism; custom entries remain untouched.
For Claude Code, both the default command and --refresh also remove the exact
legacy project-scoped npx -y prism-mcp-server entry from the effective
ancestor .mcp.json after the native user registration succeeds. No custom or
near-match project entry is changed.
Close the target MCP hosts before a non-dry-run registration so they cannot
edit their configuration at the same time.
The same connection installs the local-first orchestration contract:
Host
Managed containment
Codex
features.multi_agent=false; a 2-thread, depth-1 Terra/low fallback profile is retained for explicit re-enable
Gemini CLI
experimental.enableAgents=false
Claude Code
CLAUDE_CODE_SUBAGENT_MODEL=sonnet; managed instructions reserve it for last-resort fallback
Cursor
Canonical policy delivered through MCP initialize instructions
Claude Desktop
Canonical policy delivered through MCP initialize instructions
All five receive PRISM_AGENT_POLICY=local-first in their managed Prism MCP
entry. Routine tasks use the RAM-aware local worker; native/background fan-out
is not the default workflow. session_task_route supplies a complexity hint;
prism_infer remains the single owner of model and thinking selection and can
choose 27B when its viability gates support it.
Set PRISM_STORAGE before running prism connect to preserve an explicit
storage choice in the generated host entries. This does not change local-model
routing; Synalux cloud storage separately requires an active cloud-memory
entitlement.
Codex registration preserves unrelated ~/.codex/config.toml content, appends
only the marked Prism MCP block, and updates only the documented local-first
feature/agent keys. CODEX_HOME is respected when set and must already exist,
matching Codex's own contract. Restart Codex CLI, the
IDE extension, or the ChatGPT desktop app after connecting.
Restart the connected host and your agent now has memory backed by a local
SQLite database (~/.prism-mcp/data.db). See IDE setup
for manual configuration and host-specific paths.
Optional — local model fleet for offline tool-routing. Pull whichever fits your hardware:
ollama pull dcostenco/prism-coder:2b # 3.3 GB · on-device / lowest RAM · sees images (100% on our routing suite)
ollama pull dcostenco/prism-coder:4b # 3.5 GB · verifier · sees images (100%)
ollama pull dcostenco/prism-coder:9b # 6.7 GB · default router · sees images (95.7%, reasons before answering)
ollama pull dcostenco/prism-coder:27b # 16.8 GB · complex code / quality · text only (100%)
Prism detects both the namespaced (dcostenco/prism-coder:9b) and bare (prism-coder:9b) Ollama tags automatically.
The 2b/4b/9b tiers carry a vision tower and accept screenshots through
prism_infer({ images: [...] }) — pass absolute paths or base64. Image
requests are refused rather than answered blind when no tier (or the Layer 1
safety classifier) can actually see the image, so a text-only model is never
handed a prompt about a screenshot it never received. The 27b is text only.
What it does
Your AI agent forgets everything between sessions. Prism fixes that — and adds verification, drift detection, and multi-agent coordination on top.
Mind Palace — persistent memory that survives across sessions
Every conversation feeds a persistent store. The next session loads the right context automatically — no re-explaining.
The dashboard shows your current project state, pending TODOs, intent health, and a neural knowledge graph — all built automatically from your agent sessions.
It runs on loopback and is gated by a local token by default — run
prism dashboard to open it without signing in. This local browser step is not
a Free-plan redemption.
Requests with an untrusted Host/Origin are refused, closing the DNS-rebinding
exposure fixed in GHSA-9cvx-7x8q-3g6m. See docs/IDE_SETUP.md
to pin the token, disable it, or configure Basic Auth / JWKS.
Export — read the record outside the agent
session_export_memory writes your memory out as plain files you can read,
diff, and commit. Nothing goes through a model to produce it.
markdown human-readable — drop it in a PR to show what the agent actually did
json machine-readable — import into another Prism instance
vault zipped Markdown with YAML frontmatter and [[wikilinks]] (Obsidian, Logseq)
This is the surface to reach for when you want to answer "did the agent verify
this, or is it claiming it did?" — the export is a record you review after the
fact, in a diff or a pull request, rather than a live view you have to go and
open. The same data is available from the dashboard's Export ZIP and
Export Vault buttons.
Ask "what did I decide about the auth flow last month?" and get an answer with citations, combining vector similarity, full-text search, and graph traversal.
Session History — immutable audit trail
Every session is logged with files changed, decisions made, and TODOs. Search, filter, and replay any past session.
Inference Metrics — see where your tokens go
Every prism_infer call tracks which model handled it (local Ollama vs cloud) and how many tokens were consumed. When you save a session, Prism shows a summary:
Cloud tokens saved is the honest routing metric — it accrues only when local Ollama handles a call that would otherwise have gone to Synalux cloud inference. A compact version appears inline after every 5th prism_infer call: 📊 local 10 (83%) · cloud 2 (17%) · ~11,570 tok · avg 1,240ms · 11,570 cloud tok saved.
Local calls use actual Ollama token counts (prompt_eval_count / eval_count from Ollama); cloud calls use char/4 estimates. Metrics are tracked locally — no portal dependency, no env vars, works offline. Per-call data is also forwarded to the Synalux portal as best-effort analytics (independent of the display).
Session Drift Detection
Long agent sessions can wander from their original goal. session_detect_drift compares current work against the stated goal and returns on_track / minor_drift / major_drift so the agent can self-correct.
Behavioral Verification — catch bad edits before they happen
AI agents apply patterns from checklists without understanding the real-world impact. The verify_behavior tool challenges the agent with a scenario it must answer before editing — forcing it to think through what the end user will experience.
Agent: "I'll revert this kitchen display change"
Prism: "⚠️ Scenario: A cook sees a 3-item ticket. One item is voided.
What should the cook see after the void?"
Agent: "The ticket stays visible with the remaining 2 items."
Prism: "Correct — your revert would hide the ticket entirely."
17 built-in domains (billing, auth, ordering, clinical, HR, and more). Custom domains per workspace on Enterprise. No hooks needed — works in any MCP client.
Time Travel
Roll back to any previous session state. Compare diffs between versions. Restore a known-good state with one click.
Cognitive Routing
Three memory types, automatically sorted: episodic (what happened — session logs, decisions), semantic (what's true — facts, architecture), and procedural (how to do X — workflows, patterns). When you search, the router picks the right store instead of dumping everything.
Multi-Agent Hivemind
Coordinate multiple AI agents working on the same project. Each agen
P
Prism Coder
dcostenco·156 estrellas·
Persistent session memory for AI coding agents — local-first, with on-device inference, associative recall, and drift detection. Works with Claude Code, Cursor, and Codex.
Aún no hay lista de herramientas. Los servidores remotos la reciben tras la primera comprobación de estado.
Preguntas frecuentes
Preguntas
¿Cómo instalo Prism Coder?
Copia en esta página la configuración stdio para Cursor, Claude Desktop, Claude Code o VS Code. Usa la instalación del publicador, no un proxy de PlugMCP.
¿Prism Coder necesita una clave de API?
El publicador indica estas variables de entorno: BRAVE_API_KEY, GEMINI_API_KEY, SUPABASE_URL, SUPABASE_KEY, PRISM_USER_ID, GCP_PROJECT_ID, VERTEX_LOCATION, VERTEX_DATA_STORE_ID.
¿Qué transporte usa Prism Coder?
Prism Coder se ejecuta localmente por stdio.
¿Cuándo se comprobó Prism Coder por última vez?
Última comprobación: 2026-11-09. Persistent session memory for AI coding agents — local-first, with on-device inference, associative recall, and drift detection. Works with Claude Code, Cursor, and Codex.