Skip to content

Configuration & environment

What Where Notes
Dataset registry location COSMOTRON_REGISTRY env var Default ./database (registry.db + datasets/<id>/). Persistent — sibling of workspace/ but never inside it. See The dataset registry.
Catalogue-type profiles cosmotron_mcp/catalogue_profiles.yaml Hand-edit to add a survey family. See Catalogue-type profiles.
Cross-session memory MEMORY.md (repo root) Structured markdown records (mem-NNN, tags, supersession); retrieved per-task, written human-gated at session end. See Memory reference.
Literature search mcp-ads-arxiv MCP server External companion by estevesjh (MIT License). scripts/install.sh --literature installs + registers it (its own package + ADS_API_TOKEN). @literature_scout uses it; the core pipeline does not require it.
Per-dataset description DATA_DESCRIPTION.md in the data dir Describes the data (columns, footprint), not the task. See Writing DATA_DESCRIPTION.md.
Human-gate escape hatch COSMOTRON_GATES env var Read once at process start, cached. skip:registry,cost / accept:systematics:<check_name>. For headless/Slurm runs only — interactive runs go through a real confirmation dialogue. See Human gates.
Sync-tool watchdog budget COSMOTRON_SYNC_BUDGET_S env var Default 45s. Any non-HEAVY_TOOLS @mcp.tool running longer is treated as hung by sync_guard.py.
Cross-session memory file override COSMOTRON_MEMORY_FILE env var Overrides the default MEMORY.md path — mainly for test isolation.
Replay provenance tag COSMOTRON_CURRENT_SCRIPT env var Set by run_analysis_script/replay tooling so a generated artefact's provenance names the script that produced it. Not user-facing config.

Coordinate convention: equatorial RA/DEC only in the current release; a profile declaring galactic/ecliptic is rejected with a clear error rather than silently mis-projecting.

Remote execution on an HPC cluster

cosmoTRON can push data-bound / long-running work — ingest, spectra, covariance, systematics checks, inference — to a remote Slurm cluster, keeping the agents and session state wherever you run them. This is opt-in and per-call: nothing runs remotely unless a tool is given a jobspec naming a site. See Remote execution for the full architecture (sites.yaml, the cosmotron-remote CLI, SSH vs same-cluster transports), the Spark + Sunrise walkthrough for a concrete end-to-end setup, and Data placement & the dataset registry for where catalogues should live and why.

Model choice (local open-weights, DGX Spark)

Hard constraint: cosmoTRON runs on local open-weights models on a DGX Spark (128 GB unified memory, shared between the model and the numerical pipeline) — no closed/frontier pay-as-you-go models. Catalogues are large (a real LSS FITS catalogue can be ≈ 5.7 GB; healpy maps + NaMaster + tjpcov/pyccl need substantial RAM), so the model must stay small to leave headroom for compute — 120B-class models are out.

Recommendation (set globally, or per-agent via the agent's model: frontmatter — see Agent roster):

  • One small Qwen3 instruct model for all agents — e.g. Qwen3-30B-A3B-Instruct (MoE, ~3B active → small live footprint) or Qwen3-32B-Instruct. Use the general instruct variant, not a qwen3-coder-* coder variant — coder variants autocomplete code well but follow the operating contract (non-interactive, tool-first, no-fabrication) poorly.
  • This is why the pipeline is tool-ified: with ingest/covariance/plotting in deterministic tools, the model mostly calls tools rather than writing physics code, so one small local model can drive every agent.
  • @plot_reviewer would rely on the model's vision capability, but it's currently parked — the recommended local Ollama build (qwen3.6) is text-only, so this subagent isn't dispatched by @cosmotron until a vision-enabled endpoint is wired back in. See plot_reviewer.

Pulling and tuning the local model

This repo has been tested end-to-end against qwen3.6:35b — that's the model pinned in .opencode/agents/cosmotron.md's model: frontmatter. Start there unless you have a specific reason to deviate (see Model choice above for the general Qwen3-instruct recommendation).

ollama pull qwen3.6:35b

Context window. The agents' system prompts are long and repetitive (tool tables, operating-contract rules, retrieved memory records) — the default Ollama context window is too small to hold one comfortably alongside a real conversation. Build a larger-context tag with a Modelfile:

cat > Modelfile <<'EOF'
FROM qwen3.6:35b
PARAMETER num_ctx 262144
EOF
ollama create qwen3.6:35b-262k -f Modelfile

(This is exactly where the -262k suffix on ollama/qwen3.6:35b-262k in .opencode/agents/cosmotron.md comes from — it's a locally-built tag, not something ollama pull gives you directly.)

Register the tag with opencode. Add it under a provider's models block in ~/.config/opencode/opencode.json with "_launch": true — this is what scripts/install.sh's Ollama sampling fix (next section) looks for when rebuilding locally-launched tags:

{
  "provider": {
    "ollama": {
      "npm": "@ai-sdk/openai-compatible",
      "options": {"baseURL": "http://127.0.0.1:11434/v1"},
      "models": {
        "qwen3.6:35b-262k": {"_launch": true}
      }
    }
  }
}

Then point the orchestrator (and, by default, the rest of the roster) at it via model: ollama/qwen3.6:35b-262k in the agent's frontmatter — <provider name>/<model tag>.

Local model sampling (opencode + Ollama)

.opencode/agents/*.md pins a low temperature per agent (the orchestrator needs it especially low to stay on the plan). If you're driving the agents through a local Ollama model, that setting alone is not enough: opencode's @ai-sdk/openai-compatible provider currently never sends temperature/ top_p in the request (opencode #25755), so Ollama silently falls back to the OpenAI-spec defaults (temp=1, top_p=1) and ignores the model's own Modelfile too — the agent looks correctly configured but runs hot regardless.

scripts/install.sh offers to install a fix for this (--no-ollama-fix to skip): a small local reverse proxy (scripts/ollama-temp-proxy.py, run as the systemd --user service ollama-temp-proxy.service on 127.0.0.1:11435) that injects the missing defaults, plus a one-time rebuild of any locally-launched model tags already registered in opencode.json (presence_penalty=0, repeat_penalty=1.05 — some pulled models ship a high default presence_penalty that actively fights tool-calling under the agents' long, repetitive system prompts).

To verify it took effect: journalctl -u ollama | grep 'temp =' should show 0.100, not 1.000, during an agent run.