Published:
Meta’s new coding model is fast, unusually inexpensive, and comes in two versions with one consequential difference: the Standard route does not train on your work; the Contributor route can.
There is a version of this story that is just another benchmark roundup. This is not that story.
We put Meta’s Muse Spark 1.3 through the work we use to evaluate models at Chat-O: multi-file changes, debugging sessions, and test runs with OpenCode. One of those changes was making new chats start with a useful Chat Room by default—the Skeptic, Optimist, and Researcher—while letting every person replace that trio or start solo. That turns out to cross database state, authorization, LiveView components, the new-chat lifecycle, and tests. It is exactly the kind of work on which a coding model earns its keep.
Then we found the interesting part. The same model is sold two ways. One is already aggressively priced. The other is up to 21x cheaper—and the discount is paid for with permission to use your prompts and completions to improve future Meta models.
That is a real choice, clearly named. It is also a choice people should make with their eyes open.
Muse Spark 1.3 feels built for an engineering loop rather than a one-off answer. It stays on task across tool calls, handles a large working set, and is comfortable with the unglamorous work: following a failing test, changing several files, then checking the result.
The experience is closer to handing a clear ticket to a quick junior engineer than prompting a chatbot: still review the work, but spend less time pulling it back to the point.
It is especially comfortable with the Elixir/Phoenix patterns in this app: tracing the boundary between persisted state, a LiveView component, and the first render of a new chat—then suggesting the smallest coherent change instead of a rewrite. We are evaluating it as a possible default coding model for our OpenCode Go workflow, but that decision will come from more completed tasks—not a benchmark chart.
Chat Rooms work best when people arrive with a few thoughtful perspectives already in the room. But a “default” is not just three hard-coded names. It has to work for a new account, a person who has made custom personas, a person who wants no room at all, and a person who has deleted one of their old personas.
We did not hand Muse a database schema or a checklist of files to change. The starting point was the product request: make a useful Chat Room the default for new chats, let people choose their own roster in Settings, and do not break existing rooms. Through OpenCode, it had to trace the existing room flow, find where a new chat is initialized, recognize that a per-user preference needed durable storage, and preserve the authorization boundary around personas.
That investigation led to the shape of the implementation: a user-level setting, one resolver shared by Settings and chat startup, explicit semantics for an untouched versus empty selection, and regression tests at the authorization boundary. The finished feature touched eight files and added 211 lines across the application. We are not publishing our full repository diff, but the design is worth showing because it is the kind of detail that makes a feature dependable rather than merely demoable.
The key design decision was to distinguish three states, not two:
| Stored value | Meaning |
|---|---|
nil |
Use the platform default: Skeptic, Optimist, Researcher |
[] |
Start a new chat solo—an explicit preference, not a missing setting |
[persona_id, ...] |
Start with this person’s saved, authorized selection |
That distinction avoids a common bug: treating an empty selection as “not configured,” then silently re-adding personas the person intentionally removed.
The setting lives with the user, not in browser storage and not on an individual chat session. That means it survives devices and applies to every fresh chat.
alter table(:users) do
add :default_room_persona_ids, {:array, :binary_id}
end
The application-level resolver owns the behavior. On an untouched account it maps the three built-in titles to their current IDs; on a saved selection it returns only persona IDs that the account is allowed to use.
default_room_persona_ids(user)
The tiny public API matters more than the storage detail. Chat startup and Settings call the same resolver, so they cannot gradually develop two different definitions of “default room.”
The Settings page now lists the available personas as checkboxes, labels built-in characters, and explains the solo option plainly: uncheck everything to start alone. Submitting the form sends the selection through the LiveView component to the account layer, which persists it with a dedicated changeset.
This particular feature did not need a bespoke JavaScript state machine. The interactive HTML, validation boundary, and update flow are handled by Phoenix LiveView. That is an advantage: less duplicated client state, and one server-side source of truth for the selection.
Saving a setting is the easy part. A new chat must actually start in room mode with the saved roster, while opening an existing chat must not accidentally overwrite its history.
The Chat LiveView resolves the default when it mounts, then uses it to set both of the things the room pipeline needs:
room_mode: default_room_ids != []
room_selected_ids: default_room_ids
It repeats that resolution when the route becomes a fresh chat. That reset is important. Without it, a LiveView that had previously displayed another session could retain stale room state, or a newly saved setting would not take effect until a full browser reload.
Persona IDs are user-controlled input, even when they came from our own Settings page. The resolver therefore filters every saved ID through the same authorization boundary used by Chat Rooms: global personas and the person’s own personas survive; deleted, malformed, or somebody else’s personas are dropped.
That gives us a safe behavior for awkward but normal cases:
The regression tests cover the platform trio and preserve their order, a saved custom default, removal of a foreign persona from a saved list, and the explicit empty-list/solo choice. That is the part we care about when evaluating a coding model: not whether it can produce a convincing UI, but whether it helps carry an apparently small product request across data modeling, server-side safety, rendering, navigation, and verification.
Muse was useful here because it stayed oriented across those layers. It could discuss the migration and state semantics, then come back to the LiveView initialization and test boundary without treating them as unrelated tickets. That is a much more meaningful signal for us than asking it to solve a toy algorithm.
Meta reports a 1-million-token context window and, compared with Spark 1.2, about 20% fewer tool calls and 25% fewer tokens for comparable work. Those are vendor-reported numbers, not an independent head-to-head; they are nevertheless directionally consistent with what we saw in agentic coding tasks. Meta’s launch note
The following is Meta’s comparison card for its maximum reasoning tier—not an independent leaderboard. It is useful context, especially for coding and long-context work, but it is not a substitute for trying a model on the work you actually do.
| Benchmark | Muse Spark 1.3 | GPT-5.6 Sol | Claude Opus 5 |
|---|---|---|---|
| DeepSWE v1.1 (long-horizon coding) | 75.4 | 73.0 | 74.0 |
| Terminal-Bench 2.1 (terminal coding) | 88.8 (tied) | 88.8 (tied) | 86.7 |
| SWEAtlas CodeBase QnA | 59.4 | 53.5 | 52.7 |
| MRCR 512K to 1M (long-context retrieval) | 98.1 | 73.8 | n/a |
| GDPVal-AA v2 (knowledge work) | 1754 | 1710 | 1824 |
| OSWorld 2.0 (computer use) | 66.9 | 62.7 | 68.3 |
The sensible reading is not “it wins everything.” It does not. It looks especially compelling for coding, tool use, and long-context tasks; other models remain stronger choices for some general-agent and browsing work.
This is the part worth understanding before you point it at a repository.
| Route | Input / 1M | Output / 1M | Data-use term |
|---|---|---|---|
| Standard | $1.25 | $4.25 | Prompts and completions are not used to train Meta models |
| Contributor | $0.10 | $0.20 | You permit prompts and completions to be used to improve/train future Meta models |
Standard is already a strong value. Contributor is 12.5x cheaper on input and a little over 21x cheaper on output. That is not a coupon. It is a different agreement.
Meta is unusually direct about the distinction: Standard API content is not used to train Meta models, while the Contributor route trades a lower price for permission to use the work you send. Read the current terms before using Contributor with anything private, proprietary, or subject to a customer commitment. Meta Model API
The practical rule is simple:
This is where the distinction matters for Chat-O.
Our High Privacy mode requires zero-data-retention (ZDR) routing for each request. ZDR means the provider does not store the request; it is stricter than a promise not to train on it. OpenRouter treats the two controls separately for exactly this reason. How OpenRouter’s ZDR filtering works
We tested the Standard route at meta/muse-spark-1.3 with ZDR enforced. OpenRouter returned no matching endpoint. The available route is no-training, but it carries a 30-day retention policy. That is a respectable and clearly different policy—not one we should silently describe as High Privacy.
So the honest product rule is straightforward:
That is better than pretending every model has the same privacy properties. People should be able to choose performance, price, and data handling deliberately.
Against models we regularly evaluate, Standard Spark is cheap enough to change which tasks are practical to run:
| Model | Input / 1M | Output / 1M |
|---|---|---|
| Muse Spark 1.3 Standard | $1.25 | $4.25 |
| Claude Sonnet 5 | $2.00 | $10.00 |
| GPT-5.6 Sol | $2.00 | $10.00 |
| Claude Opus 5 | $5.00 | $25.00 |
| Gemini 3.8 Flash | $0.75 | $3.75 |
For coding agents, token price is only half the bill. Fewer tool calls and fewer retries matter just as much. That is why a model that is merely “cheap per token” can still be expensive in practice—and why Spark’s task efficiency is the part we will keep testing.
Any one of these could change the answer quickly:
Open weights would create a deployment option; they would not automatically make a service private. Privacy still depends on who runs the inference and what that operator retains.
Muse Spark 1.3 is a genuinely interesting coding model. Standard pricing is excellent, its no-training commitment is meaningful, and Contributor is a remarkably explicit data-for-price trade.
Use the Standard route when its retention policy fits the work. Keep sensitive work on a ZDR-qualified route when that is the promise you need. And do not let a 21x discount obscure what the Contributor model ID changes.
Want to compare a model on a real question instead of a benchmark chart? Start a new Chat-O chat, or bring the decision into a Chat Room and get several perspectives at once.