This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
AI-powered orchestrator ("Conductor") that accepts natural language genomics research prompts and orchestrates the 1000 Genomes analysis workflow on Kubernetes via HyperFlow WMS. Built on the mcp-agent framework (LastMile AI), it coordinates four external components: Workflow Composer (MCP server), Workflow Profiler (LangGraph agent), HyperFlow engine (Node.js WMS), and K8s deployment (Helm charts).
- Docker Desktop (or Docker Engine on Linux) — required for Kind clusters
- Devbox —
curl -fsSL https://get.jetify.com/devbox | bash
# Enter dev environment (provides kind, helm, kubectl, uv, python 3.11)
devbox shell
# Setup & install
make install # uv sync --all-extras
make setup # Full: install + cluster-create + cluster-load-images + infra-up
# Code quality
make lint # ruff check + format check
make format # Auto-format
make typecheck # mypy
# Testing
make test # Unit tests only
make test-integration # Integration tests (requires Kind cluster)
make test-e2e # E2E pipeline tests (requires Kind cluster + images)
make test-e2e-outputs # E2E output verification tests (30-90 min each)
make test-all # All of the above (excludes test-e2e-outputs)
make ci # lint + typecheck + test
# Run single test
uv run pytest tests/unit/test_models.py -v
uv run pytest tests/unit/test_models.py::test_specific_function -v
# K8s cluster
make cluster-create # Create Kind cluster (1 worker node, all pods on hfmaster)
make cluster-delete # Delete Kind cluster
make cluster-status # Show cluster/pod/helm status
make cluster-load-images # Load Docker images into Kind
# Run conductor
make run # Default prompt
make run-dry # Dry-run (no K8s deployment)
make run-query Q="..." # Custom prompt
make demo # Interactive demo (pauses between phases)
make demo-test # Non-interactive demo (no pauses, for CI/debugging)
# Cleanup
make teardown # Remove Helm releases (keep cluster)
make teardown-all # Full cleanup (cluster + releases)10-phase pipeline (Stage 2):
NL Prompt → ROUTING → PLANNING → VALIDATION (Gate 1) → PROVISIONING → DATA_PREPARATION
│ │ │ │ │
hardcoded Composer Rich UI Kind+Helm tabix K8s Job
to 1000g MCP tools approve/ hf-ops+hf-run scan VCF rows
via Agent refine/abort wait engine extract header
→ GENERATION → APPROVAL (Gate 2) → DEPLOYMENT → MONITORING → COMPLETION
│ │ │ │ │
Composer Rich UI kubectl cp Execution teardown+
MCP tool approve/abort workflow.json Sentinel summary
deterministic real task counts +columns.txt OOMKill/
generate_workflow +pop files straggler
+signal detection
The conductor does NOT use the 1000genome-data Docker image. All data flows through:
- Planning: Composer MCP tools return
download_commands(tabix URLs for region extraction) - Data Preparation: K8s Job runs tabix commands to download VCF data to NFS volume, scans row counts, extracts VCF header
- Generation: Deterministic
generate_workflowMCP tool call with actual row counts + VCF header → returns workflow.json + population-filtered columns.txt + population files - Deployment:
kubectl cpdelivers workflow.json, columns.txt, population files to engine pod, then touches.conductor-readysignal
- mcp-agent orchestration:
MCPApp+Agent+AugmentedLLMfor MCP tool calls to Workflow Composer - Stateful pipeline:
PipelineState(Pydantic BaseModel) accumulates artifacts across phases; JSON-serializable for Temporal compatibility - Context replay:
planner_historyserialized in state enables conversation history to cross Temporal activity boundaries - Context synthesis:
synthesize_context_for_composer()builds coherent context for stateless Composer calls during refinement loops - K8s via subprocess: Async wrappers around helm/kubectl (not Python K8s client); mirrors
fast-test.shflow - Conductor signal pattern: Engine command waits for
/work_dir/.conductor-ready; conductor copies workflow.json + columns.txt + population files viakubectl cpthen touches the signal file - Deterministic generation:
generate_workflowMCP tool called directly with actual VCF row counts and header (no LLM involved in generation phase) - Population-filtered columns.txt: VCF header passed to
generate_workflow→ returns columns.txt with only requested population samples (e.g., 91 GBR instead of all 2504) - LLM factory:
{"anthropic": AnthropicAugmentedLLM, "google": GoogleAugmentedLLM}— provider switchable via config - Execution Sentinel: Phase 9 delegates to
execution-sentinelpackage viaSentinel.watch()— handles OOMKill detection, straggler detection, mass-failure escalation, connectivity loss - Worker job scheduling: No nodeSelector on worker jobs — jobs run on all cluster nodes (hfmaster + hfworker). Engine/NFS/Redis pinned to hfmaster via Helm chart.
Generated values disable two upstream subchart features not needed by the conductor:
hyperflow-nfs-data.enabled: false— no data container image (conductor uses tabix Jobs)initContainers.enabled: false— no init container waiting for workflow.json from data image (conductor delivers via kubectl cp after engine starts)
NFS volume (nfs-volume subchart) remains enabled — engine pod and worker jobs share data via claimName: nfs.
| Component | Interface | Repo path (relative to hyperflow/) |
|---|---|---|
| Workflow Composer | MCP server (5 tools) | 1000genome/1000genome-workflow/workflow-composer/ |
| Workflow Profiler | Python library | 1000genome/workflow-profiler/ |
| HyperFlow K8s Deployment | Helm charts + Kind config | hyperflow-k8s-deployment/ |
| Execution Sentinel | Python library (monitoring) | 1000genome/execution-sentinel/ (GitHub: hyperflow-wms/execution-sentinel) |
| Conductor Sample | Reference mcp-agent patterns | agentic-systems/conductor-sample/ |
- Dev environment: Devbox (Nix-backed, pins kind/helm/kubectl/uv/python)
- Orchestration: mcp-agent from day 1 (not LangGraph, not raw API calls)
- Data models: Pydantic BaseModel (not dataclass) —
.model_dump()/.model_dump_json()for serialization - All timestamps:
datetime.now(UTC)(not naive datetimes) - K8s ops: subprocess helm/kubectl for MVP; kagent-tool-server in Stage 6
- K8s testing: Kind primary, kr8s for async test assertions
- Workflow delivery: Conductor signal pattern —
kubectl cp+ touch.conductor-ready(engine waits for signal before running) - No data container: All VCF data downloaded via tabix K8s Jobs from Composer's
download_commands(not from1000genome-dataDocker image) - Deterministic generation:
generate_workflowMCP tool with actual row counts (not LLM-basedestimate_variants) - Config: pydantic-settings with
HF_CONDUCTOR_prefix,__nested delimiter - CLI: Click + Rich
- Package layout:
src/workflow_conductor/withphases/,k8s/,ui/subpackages - All models in one file:
models.py— prevents circular imports - No utils/ directory: Avoid premature abstractions
Override via environment variables:
HF_CONDUCTOR_AUTO_APPROVE=true
HF_CONDUCTOR_KUBERNETES__CLUSTER_NAME=my-cluster
HF_CONDUCTOR_LLM__DEFAULT_PROVIDER=google
- After finishing work: Always commit, create a PR with
@balisas reviewer - After creating a PR: Run
/code-review:code-reviewto self-review the PR before requesting human review - After successful code review: Automatically merge the PR (no need to wait for user confirmation)
- After merging a PR: Always create an annotated git tag (e.g.,
v0.1.0-models) so we can return to that project state later
- After every PR (before code review):
make ci(unit tests + lint + typecheck) +make test-integration(K8s tests on Kind, no LLM tokens) - After every completed stage:
make test-e2e(full pipeline with real LLM tokens + Kind cluster)
When testing the demo, run make demo-test (non-interactive, no pauses) in a background shell and spawn a monitoring sub-agent that watches the demo output in a loop:
- Launch: Run
make demo-testin background via Bash tool - Monitor: Spawn a sub-agent that periodically tails the output, checking for:
- Progress: new phase headers appearing (e.g.,
[PROVISIONING],[DEPLOYMENT]) - Stalls: no new output for >30 seconds
- Errors:
failed,Error:,Traceback, non-zero exit codes
- Progress: new phase headers appearing (e.g.,
- On failure/stall: Stop the demo, investigate (check pod status, events, logs), fix the issue, and re-run
make demo-test— repeat until the demo completes successfully - Debug tools:
kubectl get pods -A,kubectl describe pod <name> -n <ns>,kubectl get events -n <ns> --sort-by=.lastTimestamp,make cluster-status
See docs/implementation-plan.md for the full plan (8 stages, 7 PRs for Stage 1). Stages 0-2.7 completed. Current version: v1.2.0 (sentinel integration).
See paper/e2e-experiment-instructions.md for the Euro-Par 2026 paper experiment plan (3 queries on 3-node k3s cluster).