v1

Version 1, currentPublished October 16, 2026

Built in public. A later version will supersede this one, and this one will stay readable at its own address.

Design review34 min read

Engineering design review: mouse-brain-ccf-join

The design review for mouse-brain-ccf-join: the problem, its constraints, the proposed design, its infrastructure, and the experiment that decides which parts stay.

In short · design review

Questions that span mouse brain datasets need joins across file formats, coordinate conventions, atlas versions and cell-type taxonomies. Each crossing has a trap that gives a plausible wrong answer and raises no error. This design puts each source behind an adapter that translates it into one shared model, checks every join for compatible versions before it runs, and records what was read so a verifier can rerun the answer. Agents reach it through an MCP server and Skills. A controlled experiment, with gold answers taken from published sources, measures what each part adds.

Question families
2
probe to cell types · projection-anchored
Data sources
3
ABC Atlas · DANDI · MouseLight
Requirements
19
each with a check
Tool conditions
4
Agent SDK; subsets in two more harnesses

Summary

  • Problem: Many questions about the mouse brain need several datasets joined in one shared 3D atlas. Each crossing between datasets has a trap that gives a wrong answer without an error, and nobody can check what an agent joined.
  • Design: A Python library translates each source, through its own adapter, into one model of atlas versions, cell-type taxonomies and observations. A join runs only between compatible versions. Every answer records what it read and every fix it applied.
  • Agent surface: An MCP server and two Skills give agents tools that find data, plan joins, refuse invalid ones, and run code in a sandbox next to the data. They work in Claude Science and in Claude Code.
  • Infrastructure: Batch work runs as Slurm jobs in Apptainer containers, which is how Claude Science computes on a cluster. The same job scripts run on the homelab's Slurm, on a Slurm cluster in AWS at the end, and on a partner's cluster. The MCP server runs as a container service.
  • Evaluation: A pre-registered experiment runs four tool conditions in the Agent SDK, and subsets of them in Managed Agents and Claude Science, against gold answers from published sources. A component stays only if it measurably helps.

The problem

A question that spans datasets

Here is a question a neuroscientist might ask an agent:

Which cell types sit in the brain region under this recording probe, and how do the neurons there respond to what the animal sees?

No single dataset answers it. v1 answers two families of question. The first is the one above. The second starts from one traced neuron and asks which cell types sit where its axon ends, and how the neurons there respond. Four public datasets hold the parts of these two questions:

DatasetWhat it holdsFormat and location
Visual Coding Neuropixels (Allen)recordings from probes in the brain. Each channel has a 3D positionNWB files on DANDI
OpenScope Neuropixels (Allen)more probe recordings, from experiments proposed by outside scientistsNWB files on DANDI
ABC Atlas MERFISH (Allen)about 4 million cells from one mouse brain, each with a position and a cell typetables and matrices in Allen's S3 bucket
MouseLight (Janelia)whole traced neurons. Each traced point has a position and a regionJSON from Janelia's NeuronBrowser

The Allen Common Coordinate Framework (CCF) links them. The CCF is a shared 3D reference atlas of the mouse brain. Each dataset places its observations in CCF coordinates and labels them with CCF regions. In software terms, the CCF is a coordinate reference system, like WGS84 for maps, and its annotation is a lookup table from a coordinate to a region id. Answering the question is a spatial join across datasets on that shared reference.

Where the joins go wrong

A spatial join is correct only when both sides agree on the axes, the units, the key and the version of the lookup table. GIS engineers know the failure: points geocoded against different datums land in the wrong place, and nothing errors. The v1 joins cross five traps of this kind. Each was checked in the public data on 2026-10-15 and 2026-10-16:

TrapSoftware analogueWhere it occurs
Broken and mirrored axesone column copied over another, and an east-west axis flippedIn the Visual Coding NWB files on DANDI, the z column repeats y, and left-right is missing (AllenSDK issue 1796). Allen's own channel table has left-right, mirrored: the true value is 11,400 µm minus it (Allen forum)
Mixed unitsone table in metres, the other in millimetresThe MERFISH coordinates are in millimetres (ABC Atlas tutorial). The probe coordinates are in micrometres
A key that looks rightjoining on another table's surrogate keyMERFISH's parcellation_index looks like a region id. It is the value in an annotation volume, and it maps to region ids through a separate table (ABC Atlas tutorial)
Two versions of the lookup tablegeocoding against two editions of a mapMouseLight stores each traced point's region under CCF 2.5 and under CCF 3, and each export carries one of them, on its own axes. For neuron AL0020 the two disagree on 296 of 466 dendrite points
Missing keysnulls in a join columnIn Allen's Visual Coding channel table, 29,311 of 123,224 channels have no region label. In one OpenScope session, 634 of 2,880 channels are labelled "void" because they sit above the brain (AIND)

Why agents make it harder

  • Size: The MERFISH brain's expression matrices take 15 GB as measured and 50 GB with imputed genes. An agent cannot read that. It calls tools or writes code, and each step can pick up a default it never sees.
  • No signal: A trap returns a plausible result, so the agent has nothing to react to.
  • No record: The answer does not say which files, versions and fixes it used, so a reviewer cannot rerun it.

What a trustworthy answer needs

A cross-dataset answer can be trusted only when four things hold:

  1. Every observation sits in one reference space, at a named atlas version, with known axes and units.
  2. Every label is an id in a named version of its ontology or taxonomy.
  3. Every join connects observations at compatible versions: the same version, or two versions linked by a recorded crosswalk. A crosswalk is a mapping table between two versions.
  4. The answer records what was read, every fix applied, and the code and environment that computed it, so a second person can rerun it.

The design enforces all four in code.

Constraints

ConstraintDetailEffect on the design
Data sizeThe MERFISH brain's expression matrices take 15 GB, or 50 GB with imputed genes. The Visual Coding dandiset holds 478 GB in 214 filesData never passes through a tool response or a context window. Code runs next to the data and returns small tables
LicencesEach source sets its own terms. The ABC Atlas and MouseLight are CC BY-NC 4.0, and the Visual Coding files on DANDI are CC BY 4.0Nothing is re-hosted or published. Every answer names each source's licence
Open data onlyEvery v1 source answers anonymous readsThe system is read-only and holds no data credentials
Upstream release cadenceEach source releases on its own scheduleVersions are explicit inputs. Contract tests on small pinned metadata catch a change
Hosts call tools differentlyClaude Science runs connector calls as code steps (docs). Claude Code calls tools by nameTools return typed, structured results that a model and a script can both read
Claude Science has no APIIts beta runs as a desktop appIts harness runs a 25-question subset, by hand
Claude Science computes through SlurmIt connects to an SSH host, such as an HPC login node. Where sbatch exists it submits jobs to Slurm, and it submits to no other scheduler. Its probe checks each host for Apptainer (docs)Batch work is Slurm jobs in Apptainer containers
Homelab firstDevelopment and the full experiment run on the homelab: Slurm through Slinky on its Kubernetes cluster (k3s), and the server on k3s. The public build moves to AWS at the endBatch work ships as Slurm job scripts and Apptainer images, and the server as a container image
One part-time developerv1 has to be finishablev1 covers two question families and three sources

Who it is for

StakeholderTheir problem todayWhat the design gives themRequirements
A scientist asking ClaudeThey cannot tell whether an agent joined the datasets correctlyAnswers that carry a record, and refusals that give the reasonR-1, R-7, R-14, R-15
An agent answering the questionThe data is too large for its context, and the traps raise no errorTools that find data, plan joins, refuse invalid ones, and run code beside the dataR-10, R-11, R-14
A reviewer, human or agentThey cannot rerun someone else's answerThe record, and a tool that reruns it and comparesR-13, R-16
An engineer adding a source, at Allen or another institutionEach integration is written from scratchOne adapter against the capability ports, with contract testsR-17
Allen's teams building AI toolsAllen's partnership with Anthropic names "multi-omic data integration" as the agents' job (Anthropic, 2026-02-02), and each of their current tools covers one sourceResults in Allen's own ids (CCF structure ids, taxonomy ids), and Skills and adapters they can adoptR-3, R-4, R-19
An operator running it on a partner institution's own HPC clusterThe system has to fit the partner's scheduler, container runtime, storage and accountsSlurm job scripts and Apptainer images, with partitions, accounts and paths as settingsR-18

Goals and non-goals

The goals, in priority order:

  1. An agent answers v1's two question families with valid joins, or refuses and says why.
  2. A verifier reruns any answer from its record and gets the same result.
  3. A new source needs one adapter. The core and the agent surface stay as they are.
  4. An experiment measures what the MCP server, the Skills and the join rules each add. The results are published whatever they show.
  5. The system runs end to end on the homelab and on AWS, and its batch work runs unchanged on a partner's Slurm cluster.

v1 leaves these out:

  • Patch-seq recordings: They use an older taxonomy with no crosswalk to the current one, and they have no CCF coordinates.
  • MICrONS: It has no CCF registration.
  • CELLxGENE Census: It excludes MERFISH, so neither v1 join needs it.
  • Search over cell types in plain language: The Brain Knowledge Platform's AI helper already does this.
  • Human or controlled-access data: Only open data is read.
  • Re-hosting data: Data is read in place. The slice cache stays private to the cluster.
  • Proposing findings: The system returns joined data, computed numbers and their records. It does not suggest biological conclusions.
  • GPUs: No v1 step needs one.

Requirements

Table 1The nineteen requirements. Each names the data model entities that carry it and, on click, the check that would show it is met.

The 28 cases on the Evidence page motivate the provenance and identity requirements. The Evidence page also maps each case to its requirements.

Proposed design

Overview

Fig. 1Ports and adapters. Callers reach the core through the agent surface. The core reaches each source through a capability port and that source's adapter. Every shape is one kind of thing, and every arrow across a dashed line names its interface. Hover a part for what it owns.

The design follows the ports-and-adapters pattern. The core holds the shared model and every rule. It defines five ports, one per capability a source can offer: spatial observations, taxonomy, physiology, morphology and expression. Each source sits behind an adapter that implements the ports it can serve. On the other side, the MCP server, the Skills and the CLI call into the core.

The example question flows through the system like this:

  1. Claude calls resolve_term, which turns the region's name into a region id in a named CCF version.
  2. Claude calls find_observations for the units recorded in that region. The DANDI adapter reads the session's units in place, takes channel positions from Allen's channel table, mirrors left-right back, and returns a handle and a count.
  3. Claude calls find_observations for the MERFISH cells in that region. The ABC Atlas adapter maps parcellation_index to region ids and converts millimetres to micrometres.
  4. Claude calls plan_join with the two handles. The planner checks that both sides use the same CCF version, or finds a crosswalk. It returns the plan and the code that runs it, or it refuses and says why.
  5. Claude calls run_plan. The code runs as a Slurm job, in an Apptainer container next to the data, and a small table comes back with a record id.
  6. A reviewer, or Claude Science's Reviewer, calls verify on the record. The verifier reruns the plan and compares the result.

Components

ComponentKindWhat it doesWhy it exists
CorePython package mouse_brain_ccf_joinHolds the model, the join planner and its checks, the records and the verifierEvery interface and every experimental condition calls the same code
Source adaptersone module per source, in the packageTranslate a source's formats, ids, axes, units and versions into the modelEach source's quirks stay in one module
Crosswalk tablesdata files in the repository, with checksumsMap region ids between CCF versions, and taxa between taxonomy versionsA join across versions needs a reviewed mapping
MCP server mouse-brain-ccf-join-mcpcontainer service over Streamable HTTP (k3s on the homelab), or a local process over stdioExposes seven typed, read-only tools over the coreAny MCP host can use the tools
Skillsfolders of instructions and tested scriptsCarry one question family each, step by stepThe multi-step workflow loads only when a task matches
CLIa console command in the packageRuns the same functions from a shell, with JSON outputContract tests, reference scripts and people use the core without an agent
Claude Science packagea connector, the imported Skills, a Specialist (Claude Science's bundle of connectors and Skills for one kind of work) and a Reviewer criterionInstalls the system in Claude ScienceClaude Science is a target host and an agent harness in the experiment
Agent partitiona Slurm partition whose jobs run in Apptainer containersRuns agent-written code and run_plan work next to the dataAgent code is untrusted, and the data is too large to move
Login nodea Slurm login node: a Slinky LoginSet on the homelab, the head node in AWSWhere Claude Science connects over SSH and submits with sbatchClaude Science computes only through Slurm
Experiment runnerSlurm job arrays, accounted by slurmdbdRuns and grades every question, condition and repeatThe sweep is thousands of attempts, and it has to resume after a failure
ImagesDockerfiles built in CI into OCI images, pushed to the homelab's Harbor registry. CI converts each batch image to one Apptainer image (SIF), once, from the OCI image's digest, and pushes the SIF to Harbor with oras://One build for every target. The server runs the OCI image, and every Slurm cluster runs the same SIF fileJobs on every cluster run byte-identical files, so a record can name the exact environment by its sha256
Slice cachehomelab storageKeeps the data slices that questions reuseRepeated reads in place are slow
Trace and run storeOpenTelemetry traces and run logsKeeps every tool call and every attemptThe experiment's evidence, and the first place to debug

Three external stores hold the data: Allen's S3 bucket, DANDI's S3 bucket and Janelia's NeuronBrowser.

How a join is kept valid

The model: The model has four kinds of thing.

  • Reference spaces: each CCF version, with its axes, unit, resolution and region ontology.
  • Taxonomies: each version of a cell-type taxonomy, with its levels.
  • Genes: each gene at a named annotation release, with its symbol history.
  • Observations: cells, units, channels and traced points. Each one has coordinates in a named reference space and labels at named versions.

Crosswalks link versions. The model is a schema. Adapters read observations on demand and return a handle to an Arrow table. No source is loaded whole.

The adapters: Each one fixes its source's traps on the way in and writes every fix to the record.

AdapterSource and formatPortsWhat it normalizes
ABC AtlasMERFISH cells, the taxonomy and CCF tables: CSV, Parquet and h5ad on S3spatial, taxonomy, expressionmillimetres to micrometres. parcellation_index to structure ids. Measured or imputed, per gene
DANDIVisual Coding and OpenScope NWB files, and Allen's channel tablespatial, physiologyChannel positions taken from Allen's channel table, since the NWB copy repeats y in z. Left-right mirrored back (11,400 µm minus the value). The QC filter stated. Unlabelled and "void" channels counted
MouseLighttraced neurons as JSON exports from NeuronBrowserspatial, morphologyBoth exports read, CCF 2.5 and CCF 3, each on its own axes. The two are kept apart, and mixing them needs a crosswalk

The planner's rules: The join planner applies five rules before any join runs.

  1. Both sides must be in the same reference space version, or linked by a crosswalk in the crosswalk tables. Otherwise the join is refused.
  2. Labels joined at a taxonomy level must come from the same taxonomy version, or be crosswalked.
  3. Joins run on ids from the region ontology. A source's own index never reaches a join.
  4. Unlabelled observations are counted and reported on the record.
  5. Every fix an adapter applied is listed on the record.

What the rules miss: Adapters fix the axis and unit traps on the way in. Rules 1, 3 and 4 catch the version, key and missing-label traps, and rule 2 does the same for taxonomy versions. The rules cannot judge whether a question makes scientific sense, and they cannot catch a trap nobody has written a rule for. Code that an agent writes without the planner is also outside their view. The experiment counts the misses: an attempt that fails on an unlisted trap gets the failure code missed_caveat, and each such trap becomes a candidate rule with an adapter test.

Tools

ToolTakesReturnsNever returns
describe_sourcesnothingthe sources, their pinned releases, the ports each serves, and their licencesfile contents
resolve_terma region, cell-type or gene name, and optionally a versionthe id at that version, its parents, and any crosswalks to other versionsdata
find_observationsa region or cell type, a kind of observation, and filtersa handle, a count, the unlabelled count, and the fields availablearrays of observations
plan_jointwo handlesa verdict (valid, valid through a crosswalk, or refused with the reason) and the code that runs the jointhe joined data
run_plana plan ida small result table and a record id. The work runs as a job on the agent partitionarrays of data
get_recorda record idthe full recordnothing else
verifya record ida match, or the first difference found on rerunnothing else

Each tool declares input and output schemas and returns structured content, so a code step in Claude Science and a model calling the tool by name read the same fields. Each is marked readOnlyHint. A refused join returns the reason and the crosswalk that would allow it. Tests hold each response under a size budget.

Design principles

Anthropic's engineering guidance gives two principles for agent tools. The design accepts the cost of each and adds a third.

PrincipleSourceWhat it costsHow the design applies it
Build tools around the tasks an agent performs, and return compact, meaningful resultsWriting effective tools for agentsA few task-shaped tools answer fewer questions directly than one tool per API endpoint, and they take more design workSeven tools, one per step of a cross-dataset question, each under a size budget
Let the agent process large data in code, and keep intermediate results out of the model's contextCode execution with MCPThe agent needs a sandbox and takes an extra step, and running code adds a security surfaceplan_join returns code. It runs in a sandbox beside the data, and only small tables come back
Anything that must happen on every answer happens in codethis designA rule catches only what someone wrote a rule forThe planner's rules and the record live in the core

Data model

Fig. 2The data model, in five groups. Crow's feet mark cardinality. The full-screen explorer is under Data model.

Reference rows are keyed by id and version together, so the same region id in two CCF versions is two rows, and a crosswalk row links them. Each observation belongs to one release and one reference space. A record lists what an answer read, each join step with its verdict, and the code and environment. A record cites only releases in the source catalogue, which is the Sources group.

One question, end to end

Fig. 3The example question, call by call. Each call adds to the record on the right. Values marked ✓ were checked against their primary source.
Fig. 4The record the example ends with.

The first family's Skill carries this workflow, and it is the template for that family's join questions.

Infrastructure

NeedDesign
Sandboxed executionAgent code runs as Slurm jobs on the agent partition, each in an Apptainer container started with --containall --cleanenv, as an unprivileged user with no credentials. The nodes' egress allows the data buckets only: a network policy on the homelab, firewall rules in AWS. A step that needs no network adds --net --network none, which unprivileged users may use
Scheduled runsA Slurm job array runs one task per question, condition and repeat. slurmdbd accounts every task, so sacct shows what ran, and a failed task requeues on its own. Each task writes its transcript and grade
Reads at scaleAdapters read objects in place with HTTPS range requests. The slice cache keeps the slices that questions reuse, on the cluster's shared filesystem
ServingThe MCP server runs as a container service behind HTTPS: a Kubernetes deployment on the homelab, on the tailnet only while in development. Each tool call is traced. Slurm runs batch work, and a long-lived server is not batch work

The same job scripts and Apptainer images run on three Slurm clusters:

  • The homelab: Slurm runs on k3s through Slinky, SchedMD's operator. No v1 step needs a GPU.
  • AWS: a Slurm cluster built from infrastructure code, in P5.
  • A partner's cluster: partitions, accounts and paths are settings.

Claude Science runs on a laptop and connects to a Slurm login node over SSH, so its data work runs as Slurm jobs too. In the Agent SDK and Claude Science, agent-written code runs on the agent partition, so the place code runs is the same in both harnesses.

Design decisions

DecisionChosenOverBecause
How sources plug inports by capabilityone interface per sourcea source with several kinds of data implements several ports, and a new source of a known kind changes nothing in the core
Where data livesa schema with handles, read in placea warehouse loaded with copiesthe licences, the size and upstream releases all rule out a copy
Where the join rules runin the corein a prompt or a Skillthe planner checks every join it plans without relying on the model
What tools returntyped, structured resultstextClaude Science reads results from code
How batch work is scheduledSlurm, with jobs in Apptainer containersKueue jobs and gVisor pods on KubernetesClaude Science computes only through Slurm and checks hosts for Apptainer, and the same job scripts run on the homelab, in AWS and on a partner's cluster
Where the server runsa container servicea Slurm jobthe server is long-lived, and Slurm schedules work that ends
Where gold answers come frompublished sources, each reproduced by a scriptan expert panelno panel is available, and a question with no published answer is labelled form-only

Trade-offs

The design gives upIn exchange forHow the cost is kept down
Breadth: two question families and three sourcesjoins that are correct and checkablea new source is one adapter
Speed of a first answer: plan, then rundata stays out of the context windowthe Skills script the common path
Effort up front: a shared model before any answeradapters that hold every source's quirksthe model covers only what the two question families need
Some answers: joins without a crosswalk are refusedwrong joins become explicit errorsrefusals carry the reason and the missing crosswalk, and the experiment counts them
Kernel isolation: Apptainer shares the host's kernel, where gVisor would intercept the agent's system callsthe container runtime Claude Science checks hosts for, so agent jobs run unchanged on a partner's clusterthe agent's user is unprivileged and holds no credentials, its egress reaches the data buckets only, and --containall hides the host's files and environment
Two substrates: Slurm for batch work, a container service for the servereach runs the work it was built foron the homelab both run on the same k3s cluster, which already runs Slinky
Sample size in Claude Science: 25 questions, by handClaude Science is in the experiment at allits results are reported with their own intervals and no decision rule

Evaluation plan

This section is the pre-registration. The question set, the gold answers, the graders and this plan are tagged in the product repository before the first full run, and the results report links to that tag.

Hypotheses

  • H1, the MCP server: On leg questions, and separately on join questions, Claude with code, Allen's libraries and the MCP server (T2) answers correctly more often than Claude with code and Allen's libraries alone (T1).
  • H2, the Skills: On join questions, adding the Skills to the MCP server (T3 against T2) raises correctness.
  • H3, the join rules: On trap questions, T2 and T3 each give the required fix or refusal more often than T1.

T0 is reported as a floor, with no hypothesis.

Three comparisons are exploratory. They are reported with intervals and carry no decision rule:

  • E1, the harness: Claude Science against the Agent SDK, with the same tools, on the Claude Science subset.
  • E2, the Reviewer: In Claude Science, whether the Reviewer criterion catches wrong joins.
  • E3, a hosted agent: Managed Agents against the Agent SDK, with the same tools, in P5.

Conditions

ConditionWhat Claude hasAgent SDK (full set)Managed Agents (full set, P5)Claude Science (subset)
T0, no toolsthe question and its own knowledgeyes
T1, the baselinea Python sandbox with Allen's libraries (AllenSDK, abc_atlas_access, pynwb)yesyes
T2, plus the MCP serverT1 and the seven toolsyesyes
T3, plus the SkillsT2 and the two Skillsyesyesyes, with the Reviewer off and on

T1 is the baseline. It gives Claude what a capable agent has today. Every condition uses one model and effort setting, named in the pre-registration tag, and the same system prompt apart from the tool description. Each answer ends with a JSON block with fixed fields, so every grader reads one format.

Question set

KindCountGold answerExample
Leg30a number from a published source, reproduced by a reference script at the pinned releaseHow many units does session 791319847 record in VISp under the AllenSDK's default QC filter? (93)
Join30form only: the join is valid, the record is complete, and a rerun reproduces the resultWhich MERFISH subclasses sit in the region under this probe?
Trap20a specific fix, or a refusalJoin this MouseLight neuron's CCF 2.5 labels to MERFISH cells

Leg questions check one dataset at a time against Allen's notebooks and two dataset papers: the AllenSDK Neuropixels tutorials, the abc_atlas_access MERFISH-to-CCF tables, Siegle et al. 2021 and Winnubst et al. 2019. No published source answers a join question, so join questions are graded on form. The report marks each form-only question as a place where expert review would go.

Size: The decision rules compare conditions within one kind, so the count per kind sets the precision. Each question is scored as its mean correctness over five runs, and conditions are compared question by question. If the per-question differences have a standard deviation near 0.5, then at 80% power and a 5% two-sided test, 30 questions detect a difference of about 25 percentage points, and 20 detect about 31. Each extra question costs a reference script or a sourced fix.

Pilot: A pilot of ten questions per kind checks the 0.5 assumption before the set is frozen. A larger spread adds questions. Questions that every condition gets right, or every condition gets wrong, are replaced. A leg question whose published number does not reproduce at the pinned release moves to form-only, and the report lists it.

Procedure and grading

Each question runs five times under each Agent SDK condition, for 1,600 attempts. Managed Agents adds 800 in P5. The Claude Science subset is 25 questions, stratified by kind and run once per cell by hand, for 75 attempts. Run order is randomised, and every transcript is stored with its token counts.

KindGrader
Legthe number must match the gold answer within the tolerance stated in the question's file
Jointhe answer's JSON block must name both sides' versions, any crosswalk, every fix and the unlabelled count, and these must match the choices a reference script makes. Rerunning the answer's own code must reproduce its table
Trapan LLM judge grades against a written rubric per question, and the author checks a random 20% of its verdicts

The leg and trap graders follow the aind-data-mcp benchmark's two modes: a match and an LLM judge. Every condition is graded from the same JSON block, so no condition needs this system's tools to pass. Every wrong attempt also gets one failure code: wrong_version, wrong_axes_or_units, wrong_key, dropped_unlabelled, wrong_level, ungrounded_number, fabricated_citation, missed_caveat or tool_call_error.

Analysis and decision rules

The primary metric is correctness per kind and condition. Each comparison reports the paired difference with a 95% interval, from a bootstrap that resamples questions and keeps each question's runs together, following Adding Error Bars to Evals. Secondary metrics are the share of answerable questions refused, the count of each failure code, and tokens per question. The report leads with the failure codes.

A component stays only if the evidence shows it helps. An interval that includes zero counts as no help.

ResultDecision
H1's interval is above zero on leg or on join questionsThe MCP server stays the main agent surface
H1's interval includes zero on both kindsThe tools shrink to what the Skills and the Claude Science connector call
H2's interval is above zeroThe Skills stay
H2's interval includes zeroThe Skills are dropped, and agents use the tools directly
H3 fails in both tool conditionsThe join rules are reworked before any other change
More than 20% of answerable questions are refused in a tool conditionThe rules are revisited for over-refusal

No target score is set in advance. The results are published with their intervals whatever they show.

Security, data handling and operations

The threat model maps every data flow and trust boundary, and records each STRIDE threat with its mitigations and status.

  • Read-only: The system reads open data and holds no data credentials.
  • Untrusted text: Free text from metadata and NWB descriptions comes back in quoted fields, and the tool descriptions mark it as data. Agent code runs only in the sandbox, so text that does steer an agent reaches no credentials.
  • Sandboxed code: Agent code runs only as Slurm jobs on the agent partition, in Apptainer containers, as an unprivileged user whose network access is limited to the data buckets.
  • Licences: Every record names the licence of each source. Anything beyond reading in place would need the data owner's agreement.
  • Adopting an upstream release: A new release becomes a change to an adapter's pinned manifest in a pull request. The contract tests run against it, and a new crosswalk is a reviewed table.
  • Contract tests: They read small pinned metadata files and run in CI on every change.
  • Public endpoint: It runs only in the AWS build. It is read-only and rate-limited, and it depends on no homelab service.
  • Hand-off: The project is done when someone new stands up the AWS build from its infrastructure code and reruns one condition from the documentation alone.

Milestones

PhaseWhat happensExit
P0, frameThis reviewthe review is accepted
P1, spikeOne reference script per v1 join that reproduces its trap and its fix. Claude Science loads a stub connector and an imported Skill, connects to a Slurm login node on the homelab, and submits a job. An Apptainer job on the agent partition reads a MERFISH slice in placeeach script matches a hand-checked value; Claude Science's job runs through sbatch; the Apptainer job's isolation flags and read rate are recorded
P2, core and adaptersThe repository mouse-brain-ccf-join is created. The model, the crosswalks, the three adapters and their contract teststhe P1 scripts' answers reproduce through the library
P3, agent surfaceThe MCP server, the Skills and the Claude Science package. The server deployed on k3s, and the agent partition on the homelab's Slurmone v1 question answered end to end in Claude Code and in Claude Science, with a record the verifier reruns
P4, experimentThe pilot, the freeze, then the full sweep as Slurm job arrays on the homelabresults published, failures first
P5, AWS build and releaseA Slurm cluster on AWS from infrastructure code, building on an earlier Terraform-built Slurm cluster that Claude Science has already driven, with the MCP server beside it. All of it in a public repository. The released package, the public endpoint, and the Managed Agents harnesssomeone new stands up the AWS build and reruns one condition from the documentation alone

Risks

RiskHow it would showMitigation
Claude Science's beta will not load the connector or the Skills, or will not run code on an SSH hostthe P1 check failsThe rest of the experiment stands without it. The report says what did not load
A trap fix is itself wrong, for example a mirror applied to files that were already righta region assigned by fixed coordinates disagrees with Allen's own channel labelsThe P1 join spike checks the fix against Allen's labels, and each fix becomes an adapter test
A published number does not reproduce at the pinned releasea reference script disagrees with its sourceManifests are pinned. The question moves to form-only, and the report lists it
Agents call MCP tools less reliably than they run codetool_call_error attempts in T2 and T3The failure code separates broken calls from wrong answers. H1 decides whether the tools stay
The question set does not separate the conditionsevery condition scores near 0% or near 100% on a kindThe pilot replaces those questions before the freeze
Apptainer will not run unprivileged inside the homelab's Slurm pods, because user namespaces are refused or the node has no FUSEthe P1 sandbox check failsA Slurm node image built with Apptainer, or a NodeSet on another node. In AWS and on a partner's cluster Apptainer runs on the host, so the risk is the homelab's alone
A source moves or changes accesscontract tests fail on a missing or moved filePaths come from pinned manifests, and every read goes through the adapter
Harbor will not store SIF files pushed with oras://. Apptainer's docs show only ghcr.iothe P1 test push failsSIF files go to the cluster's shared filesystem or an object store, keyed by their sha256, and the record names them the same way

Questions for reviewers

  1. Crosswalks between atlas versions: For MouseLight, is a crosswalk between region labels enough, or must traced points be re-registered between CCF 2.5 and CCF 3?
  2. Join granularity: v1 joins units and cells that share a region. Should it also offer joins by distance, such as the cells within 100 µm of a channel, given the registration error of each dataset?
  3. Precision: Is detecting differences of about 25 points on leg and join questions, and 31 on trap questions, enough for these decisions?
  4. The AWS build: Should it run a Terraform-built Slurm cluster on EC2, a pattern Claude Science has already driven, or AWS Parallel Computing Service, AWS's managed Slurm?
  5. An instructions-only condition: Should the experiment add a condition in which Claude is told to state its versions but has no tools? It would separate the effect of the instruction from the effect of the tools, for a quarter more attempts.

Supporting material

  1. What an answer about the brain depends on: The versioned inputs behind an answer, in depth.
  2. What already exists: The MCP servers and the assistant that already work with Allen data.
  3. Same input, different answer: Documented version changes that moved results on identical inputs.
  4. Fluent, confident, unverifiable: AI deployments in science and medicine that failed on what could not be checked.
  5. Threat model: A data flow diagram with its trust boundaries, and the STRIDE threats against each element and crossing.

The full-screen data model and every verified case, with its source, are on the Data model and Evidence pages.