cd /news/ai-tools/dissecting-claude-science · home topics ai-tools article
[ARTICLE · art-67947] src=feitong.phd ↗ pub= topic=ai-tools verified=true sentiment=· neutral

Dissecting Claude Science

Anthropic released Claude Science in beta on June 30, 2026, a daemon-centered agent harness for scientific execution, durable artifacts, and verification. The system splits kernel working state from daemon authority, enabling code compression, versioned artifacts, and external review that can block completion. The implementation examined is version 0.1.15-dev.

read23 min views1 publishedJul 6, 2026
Dissecting Claude Science
Image: Feitong (auto-discovered)

Claude Science is a daemon-centered agent harness for execution, durable artifacts, and verification.

On June 30, 2026, Anthropic released Claude Science in beta[1]. It looks like a simple local app.Starting the app unexpectedly opens a localhost page in your browser instead of a conventional desktop window. Its real novelty sits below the interface: Anthropic has turned the scientific workbench itself into an agent harness, with a daemon mediating the path from a running analysis to the evidence behind the final artifact.

The visible experience is intentionally familiar. You open a project, talk to an agent, watch it write and execute code, and receive a figure, table, structure, or report. Generated outputs can also expose the code that produced them. That code was my first way into the architecture. In one generated analysis, I found a call like this:

try:
    EMAIL = host.get_user_email()
except Exception:
    EMAIL = None

There was no import host

. There was no host

package in the Python environment. Yet the name existed inside the running kernel. A starter project contained another clue, host.exec_peek(...)

, inside its recorded code path. These small anomalies in an otherwise ordinary Python session raised the question that led me through the system: what put host there, and what is on the other side of the call?

The answer begins with a concrete mechanism. kernel_worker.py

says that the host SDK is installed through the first execute()

after kernel startup. The daemon injects that SDK, and calls such as host.llm()

and host.mcp()

become synchronous RPC back across the process boundary. That call boundary supplies the essay's spine: kernels hold working state, while the daemon holds authority and history.

From that split follow the product's three defining choices. Code compresses orchestration without collapsing capability boundaries. Artifacts outlive the conversation as versioned evidence. Review runs outside the main agent's self-reflection loop and can block completion.

For agent-harness developers, Claude Science is a useful case study in how model capability, harness policy, and application-owned execution combine into one scientific pipeline. I will follow the same boundary from beginning to end: first through the app shell and runtime payload, then through the injection and RPC behind host

, and finally through the code, artifact, and verification flows that the daemon controls. The implementation examined here is 0.1.15-dev

.The mechanism claims come from the local app bundle, the files under ~/.claude-science/runtime

, the SQLite migrations, and the behavior of the staged claude-science

daemon.

What Ships to Your Machine #

Before following host

, let me start with what any user can inspect. The macOS bundle is mostly a signed launch and update shell. It starts with a seed executable, stages a newer claude-science

daemon under the app's home directory, and lets that daemon serve the local web application on loopback. The daemon, in turn, selects a versioned runtime payload under ~/.claude-science/runtime

.

The payload identifies its build and platform in BUILD.json

. Around that small file is the actual product distribution: the web client, agent profiles, kernel workers, SQLite migrations, scientific skills, MCP servers, compute-provider code, seed projects, micromamba, image-processing dependencies, fonts, and write-tracing support. The runtime itself is replaceable; the much larger Python and R environments are provisioned separately under ~/.claude-science/conda

.

The signed shell can remain small while the daemon and product payload move quickly. In the inspected installation, baseline Python analysis, R analysis, and bundled MCP services lived in separate conda environments; individual workspaces then added local Python virtual environments and R libraries on top.

The payload also contains compressed starter projects for a CRISPR screen, enzyme engineering, extremophile analysis, and immunotherapy analysis. Their manifests and archives contain plans, reports, tables, figures, structures, arrays, intermediate results, and the recorded message streams that produced them. Because all of this lives on the user's machine, the starter projects are more than demos. They are inspectable specimens of the product's artifact model: users can see what Claude Science does, how it did it, and what quality its deliverables reach.

Following host #

Into the Daemon

The artifact code panel gives me the first clue, but the runtime explains how the trick is performed. Near kernel startup, kernel_worker.py

initializes an ordinary persistent namespace and leaves this comment:

The file contains protocol plumbing for SDK calls, but not the SDK implementation itself. That implementation is part of the claude-science

daemon, which assembles and injects it per kernel.

The daemon always sends one base fragment, then concatenates gated fragments according to the agent profile. Those later fragments attach methods to an already-created singleton. The base fragment binds that singleton to both host

and the legacy name operon

, then registers the object in sys.modules

, which is why import host

also appears to work even though no module was installed.

The same fragment answers what happens on the other side of a method call. Inside a kernel, host.llm()

, host.artifacts()

, host.mcp()

, and host.compute.create()

look like ordinary Python. Each ultimately serializes a synchronous request over the private kernel protocol and waits for a matching daemon response:

The injected methods make the SDK convenient to use; they do not grant the final authority. The daemon chooses an allowed method set for each kernel kind, checks that permit before dispatch, and lets each handler perform its own validation. Fabricating a raw _host_call("mcp", ...)

does not recover a capability omitted from the analysis kernel.

The daemon is the architectural center. It owns identity, permissions, agent frames, execution records, artifact storage, connector access, compute providers, verification state, and the local web service. Python, R, shell processes, the stdlib-only control REPL, and remote compute remain subordinate workers. Python and R can retain state, and all of these workers can calculate or produce files; none decides which external capabilities it may use or which outputs become durable.

With the physical payload and the host

boundary now connected, we can follow the consequences of that design. The first is how the agent does its work: it writes code.

Cut I: Code as the Orchestration Language #

Most agent products use some variation of a ReAct loop: reasoning, one or more tool calls, results, then another model turn. Claude Science can do that too, but its distinctive interface is code. Python expresses the control flow among tools, and the difference becomes clear at scale.

Take the literature sweep behind the shipped literature-review

skill. The skill loads helpers such as search_openalex

and expand_citations

directly into the Python kernel. One cell can pull hundreds of candidate papers, walk their citation graph in both directions, and retain the result as a table. Because model calls run inside the same kernel, a loop can call host.llm()

on each candidate to score relevance and extract its reported effect. The model writes one cell and receives one consolidated result; it does not have to manage hundreds of tool exchanges in its transcript. Matplotlib can then draw the result from the table already in memory.

Two properties make this compression possible. First, the full working set never has to enter the main agent's conversation context. It remains data inside the persistent kernel; individual host.llm()

requests cross the boundary, and only the consolidated result returns to the main transcript. Second, the iteration lives in code rather than in the model's turn-by-turn transcript. One for

loop makes N calls from inside a single cell. The model writes the loop once and reads one result. Code moves the iteration out of the language model.

Code is therefore not just a way to analyze returned data. It compresses the orchestration. The rest of this cut is the machinery that keeps that compression safe: the code runs inside capability-shaped processes, and the boundaries between them are as deliberate as the code itself.

The main OPERON

prompt states the workflow directly. MCP calls happen in repl

, not in Python or R. Loops over samples or records run inside one REPL cell. Results are serialized into ./handoff/<name>.json

, then loaded by an analysis kernel. A Python call contains a whole logical analysis step because each call costs a full model round trip even though the kernel itself persists.

The control kernel and the data kernels

The control REPL runs Python in isolated, stdlib-only mode. It receives orchestration fragments for MCP, agents, skills, frame queries, delegation, structured output, and provider-gated remote compute. The package-rich Python and R kernels do not receive those surfaces. They receive analysis-oriented methods such as artifact lookup, lineage, model calls, credentials, and analytic libraries.

When analysis code tries host.mcp

, the SDK does not pretend the method exists. Its AttributeError

says that connector tools have no surface in that kernel, tells the agent to fetch in repl

, write JSON under ./handoff

, and read it from Python. The same teaching error covers agents, skills, compute, query, frames, execution control, and structured output. It also names the process boundary: the kernels share a workspace current directory, but not LLM context or memory.

Host surface Analysis Python/R Operon control REPL Reviewer
artifacts and lineage yes yes read-only
model calls yes yes no
MCP, agents, skills no yes no
compute, delegation, output submission no profile/provider gated no
frame and database introspection no yes bounded read-only

Withholding SDK methods is only the first gate. It teaches the API by producing a useful error. Authority lies in the daemon's permit set. Even if kernel code manufactured a raw _host_call("mcp", ...)

, the analysis permit set would exclude it. The MCP handler would still require an Operon kernel, authentication, connector resolution, schema validation, and policy approval.

Code is also a capability boundary. Third-party scientific packages run in stateful analysis kernels. Connector access and agent mutation run in the narrower control kernel. A pandas object cannot pass by reference from Python into repl

; it must become a file. That conversion adds a step, but it also makes the crossing nameable, inspectable, hashable, and eligible for artifact lineage.

Persistent state without kernel authority

The Python worker is a long-lived subprocess with a persistent namespace. It accepts JSON requests, compiles each cell under a synthetic filename such as <kernel:17>

, registers source in linecache

, and evaluates it in the same namespace used by earlier cells. A loaded matrix, fitted model, or helper function can survive across turns. Each response includes stdout, stderr, trace information, wall time, CPU time, and peak memory.

Persistence comes with protocol hardening. Streaming output, final responses, and mid-cell host calls share locks so JSON lines cannot interleave. Protocol file descriptors are separated from user-visible stdout. Secret variables are removed before user code runs. Dynamic-library loads from writable roots are refused unless they fall under an explicit environment exemption. exit

, quit

, and interrupts are handled without casually destroying the kernel.

R mirrors the same broad shape. It is a long-lived Rscript

worker that retains .GlobalEnv

, exchanges JSON over standard streams, strips secrets, guards dyn.load

, and supports host callbacks during evaluation.

Bash is different: the evidence points to managed subprocess execution rather than persistent shell memory. It still participates through execution records, background output, process-group interruption, and host approvals.Python and R persistence are explicit in worker source. Shell persistence is not. On macOS, the write-trace configuration also says the Darwin path does not trace Bash in the same way as Linux.

Persistent kernels are not new. The design choice that matters here is persistence without kernel authority. A Python process may hold a giant matrix for an hour; it must still ask the daemon for a privileged host operation.

Agent-swarm orchestration through code

The control plane does not stop at compute. Its gated SDK fragments let the agent create and edit agent profiles, attach skills and connectors, edit and publish skills, delegate to, collect, and interrupt child agents, and submit structured results. These are host calls, not edits to an informal prompt file. The daemon can validate and apply policy when it builds new agents, not only when they use tools.

Onboarding uses the same runner in a deliberately narrow form. The shipped ONBOARDING

profile cannot run Python, R, Bash, repl

, search, package management, or remote compute. It conducts a bounded interview with option cards, collects permissions after a first task is selected, and hands the task to a working agent. This product flow could have been a fixed wizard. Instead it becomes a constrained agent profile inside the harness.

For harness developers, Cut I yields a specific lesson. Giving a model "code execution" is not one capability. Claude Science decomposes it into persistent data state, standard-library control code, external-tool RPC, managed subprocesses, remote jobs, and daemon-owned policy. Code joins those pieces without erasing their boundaries.

That is the first consequence of the daemon boundary: work can move across processes while authority remains centralized. Those crossings create the next problem. If results must pass through files and outlive a kernel, the system needs a durable record of what each result is and where it came from.

Cut II: Artifacts, Not Messages, Are the Product #

The OPERON

prompt tells the agent to produce artifacts, not just answers. Workspace files remain invisible to the user until they are saved. Figures should be embedded by version id. Reports should link artifacts by identity rather than by an ambiguous filename. The final response should point to the primary deliverable while the artifact tray carries the rest.

This is not presentation polish. It names the system's durable unit.

For an artifact record to be useful, it has to answer one question: what was each version built from? Claude Science answers with a dependency graph over exact versions, not filenames. The underlying mapping record can distinguish inputs found by runtime observation from inputs supplied by post-hoc reconstruction, while extraction itself may remain pending. The figure puts that distinction first; the rest of this cut explains how the evidence is recorded.

Lineage is observed before it is reconstructed

Code text alone is a poor lineage oracle. A path may be assembled dynamically. A dataframe may be sliced through library calls. A figure may be written by an object whose origin is invisible in the final savefig

statement. Claude Science first tries to observe dataflow while code runs.

Before the agent's analytical code runs, the analysis SDK wraps selected readers and writers. Readers such as pandas.read_*

, numpy.load*

, and anndata.read_h5ad

attach source version ids to returned objects. Writers such as DataFrame.to_*

, Figure.savefig

, numpy.save*

, and json.dump

harvest those tags and record which source versions reached an output path. When that path becomes an artifact, the host asks the kernel for its runtime inputs.

The mechanism propagates tags through pandas attributes, tagged NumPy subclasses, scalar wrappers, and a side table where possible. It is deliberately not universal taint tracking. Its own non-goals include generic dataflow tracing and complete R or Bash coverage. Plain dictionaries, unsupported libraries, and executed strings can lose tags. When a wrapped writer fires, its recorded input set—even an empty one—is authoritative. Only when no wrapper saw the path does the host fall back to code and dependency reconstruction.

That ordering is the important choice:

An LLM could infer every edge from code, but Claude Science uses that approach only as a fallback.Provenance confidence is uneven. Python has the richest object wrappers. R and Bash depend more on write tracing and post-hoc reconstruction, and the Darwin configuration says Bash is not traced through the same preload path as Linux. "Has lineage" should not be presented as a binary guarantee.

The record beneath the file

An artifact is not merely a path. It is a project-scoped record with versions. The artifact row identifies project, root conversation, producing frame, filename, latest version, folder, priority, and whether the item is ephemeral or user supplied. Each version can preserve content type, size, checksum, storage path, extracted code, a code description, lineage messages, agent, language, dependency mappings, environment snapshot, annotations, and parent version. Separate rows store exact version-to-version dependencies.

Beneath that record, Claude Science records at least three evidence layers.

First is the execution log. A cell can record its frame, index, kernel id, environment, language, source, stdout, stderr, status, files written, files read, and error location. An artifact version can point back to the producing cell and to cell-source snapshots.

Second is the host-call log. A privileged call made inside a cell can be stored with method, arguments, sequence number, derivability, inline or referenced response data, error, byte count, and execution-log id. This separates "the code ran" from "the code asked the host for an external or privileged result".

Third is the artifact graph. Dependencies connect exact versions, not filenames. host.lineage.graph(version_id)

returns topology cheaply; host.lineage[version_id]

can return code, messages, environment, inputs, checksums, frames, and producing cells for a selected node. The result also exposes extraction_pending

, so zero current edges need not mean an artifact has no inputs.

Together, these layers can represent: this figure came from that table, produced by this cell, after these host calls, under this environment, in this agent frame. Coverage may be incomplete, but the schema treats the chain as first-class state rather than a paragraph improvised after the fact.

How code is reconstructed behind an artifact

There is no single magical "reconstruct code" function. The system assembles several evidence lanes.

If an artifact was saved directly from a recorded cell, producing_cell_id

and cell sources provide the strongest path. For a more complex sequence, a version can store extracted_code

, code_description

, lineage_messages

, and dependency_mappings

. Environment and lineage snapshots can be addressed by hash. parent_version_id

preserves ancestry. Runtime tags may provide exact upstream ids. The daemon then converges mappings into dependency edges while checking that stored mapping text has not changed under a concurrent update.

The result follows the same confidence ordering as the lineage ladder, now viewed from the reconstruction side. The daemon prefers observed tags and producing cells. It then falls back through recorded calls, extracted code, and snapshots to post-hoc mappings, and marks whatever has not converged as pending. Some edges were observed, some reconstructed, and some remain unsettled.

Replay without pretending the host never existed

Export creates a difficult problem. Notebook code may contain host.llm()

, host.artifacts()

, host.lineage

, host.mcp()

, delegation, or app calls. Outside Claude Science, host

is not an installed package and daemon state is absent. Exporting only Python would produce a notebook whose important calls fail.

The shipped replay shim chooses a direct solution. Host responses are written to operon_tape.json

. A standalone notebook loads the tape, binds both host

and the legacy operon

name to a replay object, and consumes entries sequentially. Known discovery calls may be skipped when extracted code omits them. A method mismatch raises before the cursor advances, preventing one divergence from silently shifting every later response.

The shim mirrors model calls, artifacts, lineage, credentials, frames, children, delegation, MCP, and app tools. Its capability report admits that agents, skills, compute, and background execution controls are unavailable. Reordering calls or adding new host effects breaks the tape.

This is portability, not full recomputation. A replayed LLM answer is the answer recorded during the live run. A replayed MCP result is not a fresh query. The tape proves that exported code can execute against preserved host responses in the recorded order. It does not prove that a clean environment can regenerate those responses from the outside world. That limitation does not invalidate replay; it defines it. Instead of hiding the host dependencies until an exported notebook fails, Claude Science exports them as data.A synthetic smoke test confirmed sequential consumption, controlled skipping of a discovery entry, and soft handling of a recorded credential failure. No real exported notebook bundle was present in the inspected app data, so end-to-end export completeness remains unverified.

The artifact system turns execution into durable evidence. That evidence, in turn, makes a different kind of review possible: a reviewer can trace the saved claim back through the record without rerunning the analysis or joining the main agent's reasoning loop.

Cut III: A Reviewer Outside the Main Agent Loop #

Many agent systems leave verification inside the loop being verified. The same model produces a result, reflects on it, and decides whether the reflection is sufficient. Even when a second model is called, the main loop often decides when to call it and what to do with the answer.

Claude Science does something else: a detached verifier owned by the runner.

The inspected release ships two verification profiles, REVIEWER

and BOOKMARKER

. They are not two constantly running agents. The reviewer path is active in the observed local runtime. The bookmarker implementation ships in the same release, but bookmarks_enabled

defaults to false, and no local bookmarker frame or transcript annotation was observed.

What the reviewer is told to do

REVIEWER

is not a second scientist. It reads the main agent's transcript and reports where the work fabricated a result, hallucinated a source, or drifted from the plan. Its prompt is unusually strict about method. Its first rule is trace, don't recompute: if the agent claims a number, the reviewer finds the cell that printed it and looks for a contradiction. A value it cannot trace inside its window is not, on its own, a finding. Two independent analyses can disagree because they chose different filters, libraries, or random seeds. That disagreement alone does not show which analysis followed the user's work. A tracing reviewer asks a narrower question: does the durable claim agree with the evidence path that the session says produced it?

To hold the reviewer to that question, the profile strips away tools that would let it start another analysis. It disables planning, delegation, web search, and thinking. It also excludes Python, R, Bash, package and environment management, artifact writing, file editing, full-text retrieval, and compute. The daemon grants only a read-only host surface: frames, scoped queries, artifact paths and listings, and lineage.

The second rule is where the design shows its priorities: the reviewer weights a finding by where the claim lives. A wrong number in a saved figure or report is one the user cites next week with no transcript beside it, so artifacts are held to a strict bar. A loose phrase in chat scrolls away, so it is flagged only if acting on it would actually mislead. The reviewer guards the durable record, not the chatter.

These choices are measured, not asserted. The code that disables thinking notes that thinking cost about 72% of the reviewer's output tokens for roughly zero recall gain on trace-the-value work; the code that withholds Python notes that across thirty production reviewer rounds, Python was 41% of tool calls, all of it the recomputation the rubric forbids. The reviewer was benchmarked into place.Both agents were tuned against a real eval, not just written, with a warning in the code against hand-editing the prompts unless you re-run it.

The BOOKMARKER

reuses the same checkpoint machinery for a narrower purpose: leave breadcrumbs a returning user can click straight back to, at most two verbatim quotes per window and often none. Its prompt was hill-climbed against an eval of 62 gold-labeled checkpoint windows, and its own comments warn against editing the wording without re-running that eval, because several plausible-looking edits measurably regressed the score.Two reviewer frames and four passing verification_checks

rows appeared here, no bookmarker frame. That shows review runs, not that it is accurate.

It runs as detached windows, not a cron

Review does not fire on a clock. Immediately before the runner dispatches a batch of tool calls, it asks two things: has enough time passed since the last checkpoint, and has real work accumulated since? At the defaults, at least 120 seconds must have passed, and one of three signals must be present: three new artifacts, a structural Markdown block, or two thousand characters of authored input. Quiet waiting triggers nothing; activity without a qualifying signal triggers nothing.

When a checkpoint fires, the verifier snapshots a bounded window: messages plus execution, artifact, plan, and provenance context. It then dispatches a detached reviewer. If one is already busy, the new unit merges into the pending window; otherwise the hold timer lets nearby work coalesce first. The figure lays out the predicate, both timers, and the detached reviewer's return at a terminal barrier"Background" is precise: a review stays in flight, but the trigger is still checked at runner boundaries, not on a wall-clock..

Review can change control flow

The reviewer participates in flow control.

Natural completion passes through a terminal reviewer barrier. The barrier decides whether the unreviewed tail needs a final checkpoint, dispatches any held unit, and waits for in-flight or pending review. It then drains the review notices. If one should be delivered, the runner injects it into the session, increments a bounce counter, saves state, and vetoes completion so the main agent must continue.

The bounce count is bounded at three by default. This prevents the reviewer and main agent from trapping the session in an unlimited dispute.

The strongest case is a delegated result. When a sub-agent hands a structured output up to its parent and a reviewer fails it first, the runner throws the output away before the parent sees it and sends the sub-agent back to fix or rebut the finding and call submit_output

again. The parent gets nothing until a corrected result comes back, or the retry budget runs out. The reviewer can void a handoff between agents, not just flag it.

What the Three Cuts Reveal #

Claude Science is not merely an AI that writes Python for scientists. It is a daemon-centered harness that governs the path from work to evidence. Kernels retain the state needed for long-running analysis, but the daemon retains authority. Code compresses the work, but capability boundaries still hold. Artifact records can preserve the result together with versions, inputs, execution, and environment. Review checks that record from outside the main loop and can stop a result from advancing.

None of that is specific to science. A serious domain agent is not built by adding a longer system prompt or a wider tool menu. It is built by deciding which objects must endure, which boundaries must remain enforceable, and where the system can still interrupt the agent when the evidence disagrees. Claude Science's most useful lesson is therefore not a feature. It is an architecture: working state in the kernels, authority and history in the daemon, and a continuous evidence path between them.

Three Predictions

The architecture above is what I could observe in 0.1.15

. The next three claims are predictions, not reverse-engineering findings. They also draw on the trajectory I have watched in Claude Code: a harness does not merely expose model capabilities. The real workflows and feedback that accumulate through it can also shape the models that follow; Anthropic's opt-in Development Partner Program explicitly describes using shared Claude Code sessions to improve models[2]. On that basis, I expect:

  • Anthropic will train or fine-tune a model specialized for life sciences, built on Opus or Fable.
  • Claude Science will reach v1.0 alongside a major model release. Whether or not that model is explicitly specialized for life sciences, the workflows and feedback accumulated through Claude Science will help shape it, much as I believe Claude Code has shaped Anthropic's recent coding models.
  • Anthropic has already conducted and supported wet-lab studies [3]. I expect those initiatives to tighten the feedback loop among model, harness, and laboratory, accelerating their coevolution.

These are predictions. The architecture above is why I find them plausible, and why I want to see what this product becomes.

── more in #ai-tools 4 stories · sorted by recency
── more on @anthropic 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/dissecting-claude-sc…] indexed:0 read:23min 2026-07-06 ·