# Project export: CryoBrain

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: UC Berkeley AI Hackathon 2026
- Tagline: CryoBrain: Verifiable AI training for better quantum-decoder hardware.
- Devpost: https://devpost.com/software/cryobrain
- GitHub: https://github.com/ayushozha/CryoBrain
- Team: 1 GitHub contributor(s) — Ayush Ojha (66 commits)

## Devpost submission (written by the team)

### Inspiration

Quantum computers need fast, reliable error correction to become useful. A big part of that problem is the decoder: the hardware/software path that turns noisy syndrome measurements into corrections before errors compound. We built CryoBrain because most AI-for-hardware demos stop at generated code or proxy scores. We wanted a system where agents could propose hardware improvements, test them against real verification and measurement tools, learn from research, and leave behind artifacts that judges can actually inspect. What It Does CryoBrain runs a multi-agent refinement loop for quantum-decoder hardware. Each iteration proposes decoder/FIFO design changes, measures them through a real toolchain, records verification artifacts, and archives the evidence. The reward is grounded in measured behavior rather than a mock demo: [ reward \approx f(\text{logical error suppression}, \text{latency}, \text{area}, \text{validity}) ] The project includes: A measured RL/refinement loop 50 archived sponsor-backed training iterations Verifiable artifacts for each iteration Offline demo dashboard Memory A/B tracking with honest parity reporting Pareto frontier views for hardware tradeoffs Sponsor integrations for research, model generation, remote measurement, and eval proof How We Built It We built the project as a Python-based hardware-design training environment. The core loop runs agents that propose, generate, verify, measure, score, and archive hardware variants. The system uses real hardware tooling where possible: Verilator for simulation, Yosys for synthesis-style metrics, Stim for quantum-error simulation, and Python orchestration for the RL loop. We also integrated sponsor platforms: Exa for research context, Fireworks for proposal generation, Modal for remote measurement, and HUD for evaluation gating. For the final proof run, we executed 50 sponsor-backed refinement iterations and archived each cycle under artifacts/marathon_runs/cycle_###, with a summary validator confirming the artifacts are present and measurable. Challenges We Faced The hardest part was keeping the evidence honest. It is easy to make an AI system look like it is improving if the reward is synthetic or if artifacts are overwritten. We had to build checks that preserved every iteration and verified that the data was real. We also had to fix claim discipline around memory. The memory A/B evidence showed parity, not an advantage, so we changed the demo and validators to avoid claiming memory improved the run unless the endpoint delta is strictly positive. Another challenge was making the project submission-clean: removing local developer paths, avoiding committed secrets, keeping sponsor evidence verifiable, and ensuring the dashboard only presents measured artifacts. What We Learned We learned that AI agents can be useful for hardware design only when their outputs are tied to real verification. The interesting part is not just generating RTL; it is closing the loop between research, candidate generation, simulation, scoring, and auditability. We also learned that honest negative or neutral results matter. Memory parity is still useful evidence because it prevents overclaiming and makes future improvement measurable. What's Next Next, we want to push beyond parity into real memory-driven improvement, expand the decoder search space, add stronger formal verification, and run longer training loops with richer research ingestion.

## README (from the GitHub repository)

<p align="center">
  <img src="docs/assets/cryobrain-banner.png" alt="CryoBrain — The AI hardware lab for quantum chip design" width="100%" />
</p>

# CryoBrain

**The AI hardware lab for designing the full quantum chip, starting with the brain that keeps it alive.**

[![Status](https://img.shields.io/badge/status-demo--ready-brightgreen)](#status-at-a-glance)
[![Demo Video](https://img.shields.io/badge/demo-watch%20on%20YouTube-red?logo=youtube)](https://youtu.be/-cI-zxsLctQ)
[![Live Demo](https://img.shields.io/badge/live%20app-GitHub%20Pages-0a84ff)](https://ayushozha.github.io/CryoBrain/)
[![Spec](https://img.shields.io/badge/spec-v6.1-blue)](docs/specs/SPEC-v6.1-checkpointed.md)
[![Python](https://img.shields.io/badge/python-3.11--3.12-blue)](pyproject.toml)
[![React](https://img.shields.io/badge/react-vite%20%2B%20three.js-61dafb)](web/README.md)
[![Evidence](https://img.shields.io/badge/evidence-50%20sponsor--backed%20iterations-6f42c1)](artifacts/measured_50_iteration_summary.json)

CryoBrain is a measured agentic hardware-design platform. Today it proves the loop on quantum-decoder and FIFO hardware targets: agents research, propose, generate RTL, simulate, synthesize, verify, score, remember, and improve against real artifacts. The bigger vision is full chip design: an AI lab that co-designs the decoder, dataflow, memory, control, verification, and cryogenic hardware stack for future quantum processors.

The pitch is simple: **every quantum chip needs a brain. CryoBrain is the swarm that designs that brain today, and the path to AI-designed full-chip systems tomorrow.**

## Contents

- [Why This Exists](#why-this-exists)
- [Status At A Glance](#status-at-a-glance)
- [What Is Built](#what-is-built)
- [Evidence](#evidence)
- [Architecture](#architecture)
- [Demo](#demo)
- [Demo Video](#demo-video)
- [Quick Start](#quick-start)
- [Configuration](#configuration)
- [Repository Map](#repository-map)
- [Verification](#verification)
- [Built With](#built-with)
- [Roadmap](#roadmap)
- [Contributing Invariants](#contributing-invariants)
- [License](#license)

## Why This Exists

Quantum computers will not scale without real-time error correction. That means future chips need more than qubits: they need an on-chip intelligence layer that can interpret syndrome streams, choose corrections, respect cryogenic hardware budgets, and keep the machine alive.

Most AI hardware demos stop at generated code or proxy scores. CryoBrain is built around a stricter rule:

```text
worse RTL -> worse measured behavior -> lower reward
```

The system is useful only if a proposed design survives measurement and verification. That is why the repo is organized around measured artifacts, not screenshots or synthetic claims.

The current implementation is the slow design loop: an AI swarm improves hardware designs offline. The full-chip vision is the fast loop: the learned NPU-style brain eventually sits inside the quantum control stack and helps run the chip in real time. The README sells that full vision, while the status table below separates what is actually built from what remains the roadmap.

## Status At A Glance

| Area | Status | Evidence |
|------|--------|----------|
| Measured reward spine | Built and validated | `score_measured`, Stim vectors, Verilator, Yosys; C0-C10 gate passes |
| Quantum-decoder task | Built, early climb | `artifacts/measured_climb.json`; golden baseline is landed, multi-step decoder improvement is still limited |
| FIFO hardware target | Built, improving | 50/50 marathon iterations show positive FIFO throughput delta |
| 50 sponsor-backed marathon | Built and archived | `artifacts/marathon_runs/cycle_001` through `cycle_050`; summary in `artifacts/measured_50_iteration_summary.json` |
| Research adoption loop | Built | Exa research context is threaded into proposal/memory artifacts and the swarm event bus |
| Offline demo dashboard | Built | `demo/index.html`, generated from measured artifacts only |
| React/Three pitch site | Built on this branch | `web/`, a 14-section scrollytelling app bound to `web/public/data/cryobrain.json` |
| Memory A/B | Evidence present, no advantage claim | 50/50 iterations report `memory_parity`; `memory_wins=0` |
| Full chip design platform | Vision, partially proven by two hardware targets | Current proof covers decoder + FIFO; roadmap expands to broader chip subsystems |
| In-chip real-time NPU brain | Vision | Not claimed as built in this repo |

## What Is Built

CryoBrain is a nine-role hardware-design swarm:

| Role | Responsibility | Current implementation |
|------|----------------|------------------------|
| Research | Pull current decoder/QEC context and provenance | Exa-backed context packs |
| Planner | Choose the next experiment direction | Planner climb artifacts |
| Architect | Propose candidate decoder/NPU configurations | Fireworks-enabled proposer with deterministic fallback |
| RTL | Generate synthesizable SystemVerilog | `cryobrain/rtl_gen/` and task RTL outputs |
| Measurement | Run measured simulations and hardware metrics | Stim, Verilator, Yosys, FIFO throughput |
| Verifier | Enforce L1-L5 checks | Functional, accuracy, formal-when-available, synthesis, budget |
| Scorer | Convert measured behavior into reward | Measured-only reward path |
| Memory | Store verified winners and provenance | JSONL memory records and A/B evidence |
| Visualization | Render the audit trail | Offline dashboard bound to measured artifacts |

The core loop is:

```text
Research -> Planner -> Architect -> RTL -> Measurement -> Verifier -> Scorer -> Memory
            ^_______________________________________________________________|
```

The loop is intentionally not just "AI writes Verilog." It is an evidence machine: every useful claim should point at an artifact.

## Evidence

The strongest current proof is the sponsor-backed marathon:

| Evidence | Current value |
|----------|---------------|
| Completed iterations | 50 |
| Steps per agent per iteration | 2 |
| Archived iteration directories | 50 |
| Required live sponsors | HUD, Exa, Fireworks, Modal |
| FIFO iterations with positive throughput delta | 50 |
| Decoder iterations with positive delta | 0, because the decoder is already at the golden baseline in these runs |
| Memory iterations marked as wins | 0 |
| Memory status | `memory_parity` |
| Measured Pareto points | 26 total, 22 frontier points |

Key files:

- `artifacts/measured_50_iteration_summary.json` - top-level marathon summary.
- `artifacts/marathon_runs/cycle_001/` ... `cycle_050/` - archived measured evidence per iteration.
- `artifacts/measured_fifo_climb.json` - FIFO throughput improvement evidence.
- `artifacts/measured_climb.json` - decoder measured climb evidence.
- `artifacts/measured_memory_ab.json` - memory A/B artifact; currently parity, not advantage.
- `artifacts/measured_pareto.json` - measured design frontier.
- `artifacts/verification_report.json` - L1-L5 verification summary.

## Architecture

```mermaid
flowchart LR
    research["Research<br/>Exa context + provenance"]
    planner["Planner<br/>experiment direction"]
    architect["Architect<br/>candidate design"]
    rtl["RTL<br/>SystemVerilog generation"]
    measure["Measurement<br/>Stim + Verilator + Yosys"]
    verify["Verifier<br/>L1-L5 gates"]
    score["Scorer<br/>measured reward"]
    memory["Memory<br/>verified winners"]
    demo["Demo<br/>measured dashboard"]

    research --> planner --> architect --> rtl --> measure --> verify --> score --> memory
    memory --> planner
    measure --> demo
    verify --> demo
    score --> demo
```

The measured reward path is the moat:

1. Generate a hardware candidate.
2. Run real simulation / measurement.
3. Reject invalid or over-budget designs.
4. Score only measured behavior.
5. Archive the result so the claim can be audited later.

The full-chip design vision extends this same loop beyond the current decoder/FIFO targets: interconnect, memories, control, calibration 

[README truncated for size]

## Detected evidence (automated analysis)

Indexed codebase: 528 recognized source files, 5495 KB.
- HTML (language) — detected in the code
- OpenAI (technology) — detected in the code
- Python (language) — detected in the code
- React (technology) — detected in the code
- TypeScript (language) — detected in the code
- CSS (language) — claimed on Devpost, not found in the code
- JavaScript (language) — claimed on Devpost, not found in the code

## Codebase structure (from repository index)

### Files (120 of 3940)

```
.dockerignore
.gitattributes
.github/workflows/deploy-web.yml
.gitignore
.python-version
artifacts/baselines/ler_baselines.json
artifacts/marathon_runs/cycle_001/design_runs/d000/d003-1782049651793017164.json
artifacts/marathon_runs/cycle_001/design_runs/d000/d003-1782049651807951034.json
artifacts/marathon_runs/cycle_001/design_runs/d000/design_config.json
artifacts/marathon_runs/cycle_001/design_runs/d000/generated_decoder.sv
artifacts/marathon_runs/cycle_001/design_runs/d000/memory_update.json
artifacts/marathon_runs/cycle_001/design_runs/d000/plan.json
artifacts/marathon_runs/cycle_001/design_runs/d000/research_context.json
artifacts/marathon_runs/cycle_001/design_runs/d000/run_summary.md
artifacts/marathon_runs/cycle_001/design_runs/d000/score.json
artifacts/marathon_runs/cycle_001/design_runs/d000/stim_ler_result.json
artifacts/marathon_runs/cycle_001/design_runs/d000/verification_report.json
artifacts/marathon_runs/cycle_001/design_runs/d000/verilator_result.json
artifacts/marathon_runs/cycle_001/design_runs/d000/yosys_metrics.json
artifacts/marathon_runs/cycle_001/design_runs/d001/d004-1782049658378038117.json
artifacts/marathon_runs/cycle_001/design_runs/d001/d004-1782049658387641331.json
artifacts/marathon_runs/cycle_001/design_runs/d001/design_config.json
artifacts/marathon_runs/cycle_001/design_runs/d001/generated_decoder.sv
artifacts/marathon_runs/cycle_001/design_runs/d001/memory_update.json
artifacts/marathon_runs/cycle_001/design_runs/d001/plan.json
artifacts/marathon_runs/cycle_001/design_runs/d001/research_context.json
artifacts/marathon_runs/cycle_001/design_runs/d001/run_summary.md
artifacts/marathon_runs/cycle_001/design_runs/d001/score.json
artifacts/marathon_runs/cycle_001/design_runs/d001/stim_ler_result.json
artifacts/marathon_runs/cycle_001/design_runs/d001/verification_report.json
artifacts/marathon_runs/cycle_001/design_runs/d001/verilator_result.json
artifacts/marathon_runs/cycle_001/design_runs/d001/yosys_metrics.json
artifacts/marathon_runs/cycle_001/design_runs/d002/d005-1782049665028691511.json
artifacts/marathon_runs/cycle_001/design_runs/d002/d005-1782049665041623526.json
artifacts/marathon_runs/cycle_001/design_runs/d002/design_config.json
artifacts/marathon_runs/cycle_001/design_runs/d002/generated_decoder.sv
artifacts/marathon_runs/cycle_001/design_runs/d002/memory_update.json
artifacts/marathon_runs/cycle_001/design_runs/d002/plan.json
artifacts/marathon_runs/cycle_001/design_runs/d002/research_context.json
artifacts/marathon_runs/cycle_001/design_runs/d002/run_summary.md
artifacts/marathon_runs/cycle_001/design_runs/d002/score.json
artifacts/marathon_runs/cycle_001/design_runs/d002/stim_ler_result.json
artifacts/marathon_runs/cycle_001/design_runs/d002/verification_report.json
artifacts/marathon_runs/cycle_001/design_runs/d002/verilator_result.json
artifacts/marathon_runs/cycle_001/design_runs/d002/yosys_metrics.json
artifacts/marathon_runs/cycle_001/design_runs/d003/d006-1782049671486282341.json
artifacts/marathon_runs/cycle_001/design_runs/d003/d006-1782049671496914425.json
artifacts/marathon_runs/cycle_001/design_runs/d003/design_config.json
artifacts/marathon_runs/cycle_001/design_runs/d003/generated_decoder.sv
artifacts/marathon_runs/cycle_001/design_runs/d003/memory_update.json
artifacts/marathon_runs/cycle_001/design_runs/d003/plan.json
artifacts/marathon_runs/cycle_001/design_runs/d003/research_context.json
artifacts/marathon_runs/cycle_001/design_runs/d003/run_summary.md
artifacts/marathon_runs/cycle_001/design_runs/d003/score.json
artifacts/marathon_runs/cycle_001/design_runs/d003/stim_ler_result.json
artifacts/marathon_runs/cycle_001/design_runs/d003/verification_report.json
artifacts/marathon_runs/cycle_001/design_runs/d003/verilator_result.json
artifacts/marathon_runs/cycle_001/design_runs/d003/yosys_metrics.json
artifacts/marathon_runs/cycle_001/design_runs/d004/d007-1782049678237464182.json
artifacts/marathon_runs/cycle_001/design_runs/d004/d007-1782049678247023088.json
artifacts/marathon_runs/cycle_001/design_runs/d004/design_config.json
artifacts/marathon_runs/cycle_001/design_runs/d004/generated_decoder.sv
artifacts/marathon_runs/cycle_001/design_runs/d004/memory_update.json
artifacts/marathon_runs/cycle_001/design_runs/d004/plan.json
artifacts/marathon_runs/cycle_001/design_runs/d004/research_context.json
artifacts/marathon_runs/cycle_001/design_runs/d004/run_summary.md
artifacts/marathon_runs/cycle_001/design_runs/d004/score.json
artifacts/marathon_runs/cycle_001/design_runs/d004/stim_ler_result.json
artifacts/marathon_runs/cycle_001/design_runs/d004/verification_report.json
artifacts/marathon_runs/cycle_001/design_runs/d004/verilator_result.json
artifacts/marathon_runs/cycle_001/design_runs/d004/yosys_metrics.json
artifacts/marathon_runs/cycle_001/measured_climb.json
artifacts/marathon_runs/cycle_001/measured_fifo_climb.json
artifacts/marathon_runs/cycle_001/measured_memory_ab.json
artifacts/marathon_runs/cycle_001/measured_pareto.json
artifacts/marathon_runs/cycle_001/planner_climb.json
artifacts/marathon_runs/cycle_001/summary.json
artifacts/marathon_runs/cycle_001/verification_report.json
artifacts/marathon_runs/cycle_002/design_runs/d000/d003-1782049857362592452.json
artifacts/marathon_runs/cycle_002/design_runs/d000/d003-1782049857375287541.json
artifacts/marathon_runs/cycle_002/design_runs/d000/design_config.json
artifacts/marathon_runs/cycle_002/design_runs/d000/generated_decoder.sv
artifacts/marathon_runs/cycle_002/design_runs/d000/memory_update.json
artifacts/marathon_runs/cycle_002/design_runs/d000/plan.json
artifacts/marathon_runs/cycle_002/design_runs/d000/research_context.json
artifacts/marathon_runs/cycle_002/design_runs/d000/run_summary.md
artifacts/marathon_runs/cycle_002/design_runs/d000/score.json
artifacts/marathon_runs/cycle_002/design_runs/d000/stim_ler_result.json
artifacts/marathon_runs/cycle_002/design_runs/d000/verification_report.json
artifacts/marathon_runs/cycle_002/design_runs/d000/verilator_result.json
artifacts/marathon_runs/cycle_002/design_runs/d000/yosys_metrics.json
artifacts/marathon_runs/cycle_002/design_runs/d001/d004-1782049863861319491.json
artifacts/marathon_runs/cycle_002/design_runs/d001/d004-1782049863873431498.json
artifacts/marathon_runs/cycle_002/design_runs/d001/design_config.json
artifacts/marathon_runs/cycle_002/design_runs/d001/generated_decoder.sv
artifacts/marathon_runs/cycle_002/design_runs/d001/memory_update.json
artifacts/marathon_runs/cycle_002/design_runs/d001/plan.json
artifacts/marathon_runs/cycle_002/design_runs/d001/research_context.json
artifacts/marathon_runs/cycle_002/design_runs/d001/run_summary.md
artifacts/marathon_runs/cycle_002/design_runs/d001/score.json
artifacts/marathon_runs/cycle_002/design_runs/d001/stim_ler_result.json
artifacts/marathon_runs/cycle_002/design_runs/d001/verification_report.json
artifacts/marathon_runs/cycle_002/design_runs/d001/verilator_result.json
artifacts/marathon_runs/cycle_002/design_runs/d001/yosys_metrics.json
artifacts/marathon_runs/cycle_002/design_runs/d002/d005-1782049870394086827.json
artifacts/marathon_runs/cycle_002/design_runs/d002/d005-1782049870407030807.json
artifacts/marathon_runs/cycle_002/design_runs/d002/design_config.json
artifacts/marathon_runs/cycle_002/design_runs/d002/generated_decoder.sv
artifacts/marathon_runs/cycle_002/design_runs/d002/memory_update.json
artifacts/marathon_runs/cycle_002/design_runs/d002/plan.json
artifacts/marathon_runs/cycle_002/design_runs/d002/research_context.json
artifacts/marathon_runs/cycle_002/design_runs/d002/run_summary.md
artifacts/marathon_runs/cycle_002/design_runs/d002/score.json
artifacts/marathon_runs/cycle_002/design_runs/d002/stim_ler_result.json
artifacts/marathon_runs/cycle_002/design_runs/d002/verification_report.json
artifacts/marathon_runs/cycle_002/design_runs/d002/verilator_result.json
artifacts/marathon_runs/cycle_002/design_runs/d002/yosys_metrics.json
artifacts/marathon_runs/cycle_002/design_runs/d003/d006-1782049876978818450.json
artifacts/marathon_runs/cycle_002/design_runs/d003/d006-1782049876989656258.json
artifacts/marathon_runs/cycle_002/design_runs/d003/design_config.json
[3820 more files omitted for size]
```

### Dependencies

- pyproject.toml: cocotb@==2.0.1, cocotb-bus@==0.3.0, cocotb-coverage@==2.0, exa-py@>=1.0, hud-python[agents]@>=0.6.5, hypothesis@==6.152.7, matplotlib@>=3.8, modal@>=0.67, modal@>=0.67, numpy@>=1.26, openai@>=1.0, pydantic@>=2.0.0, pymatching@>=2.0, python-dotenv@>=1.0, pyuvm@==4.0.1, stim@>=1.14
- web/package.json: @react-three/drei@^9.114.3, @react-three/fiber@^8.17.10, @types/react@^18.3.12, @types/react-dom@^18.3.1, @types/three@^0.169.0, @vitejs/plugin-react@^4.3.4, react@^18.3.1, react-dom@^18.3.1, three@^0.169.0, typescript@^5.6.3, vite@^5.4.11

### Recent commits (newest first)

- Merge pull request #25 from ayushozha/feat/readme-demo-video-banner
- docs: add README banner and YouTube demo video
- Merge pull request #24 from ayushozha/feat/deploy-github-pages
- ci: deploy CryoBrains web app to GitHub Pages
- Merge pull request #23 from ayushozha/feat/cryobrains-react-app
- docs: sell full-chip CryoBrain vision
- feat: CryoBrains React app bound to real measured artifacts
- Merge pull request #22 from ayushozha/codex/50-sponsor-marathon
- feat: archive sponsor marathon evidence
- Merge pull request #21 from ayushozha/feat/spec-v61-checkpoints
- fix: address spec review blockers
- feat: enforce sponsor-backed spec v6.1 artifacts
- feat: multi-hour improvement marathon with pareto decoder acceptance
- docs: sync progress to SPEC-v6.1 green and demo-ready state
- feat: surface FIFO improvement in offline demo
- feat-complete-SPEC-v6.1-checkpoints-C0-C10
- feat: wire research adoption and SPEC-v6.1 artifact export
- feat: real measured artifacts, measured-only demo, SPEC-v6 progress
- Merge pull request #19 from ayushozha/feat/spec-v6-swarm
- feat: SPEC-v6 swarm bus, L3/report, planner, and measured-first demo

## Key source files (fetched from GitHub, selected and truncated for size)

### SPEC5.md

```markdown
# Moved

Canonical spec: **[docs/specs/SPEC-v5.md](docs/specs/SPEC-v5.md)**

Spec index: **[docs/specs/README.md](docs/specs/README.md)**

Agent orchestration: **[docs/agents/README.md](docs/agents/README.md)**

Tell Codex / Claude / Grok:

- `Read docs/agents/HANDOFF-CODEX.md and execute it.`
- `Read docs/agents/HANDOFF-CLAUDE.md and execute it.`
- `Read docs/agents/HANDOFF-GROK.md and execute it.`
```

### THIRD_PARTY_NOTICES.md

```markdown
# Third-Party Notices

This repository vendors a small subset of third-party HDL code for the
reference tasks. Runtime HUD tasks should use the checked-in vendored files and
must not fetch third-party libraries from the internet.

## BaseJump STL

Paths:

- `tasks/stream_arb_fifo_cocotb_dv/vendor/basejump_stl`
- `tasks/stream_arb_fifo_formal/vendor/basejump_stl`

Upstream project: <https://github.com/bespoke-silicon-group/basejump_stl>

Use in this repository: the CocoTB DV and Formal reference tasks use minimal
vendored subsets of BaseJump STL to build a two-lane stream FIFO wrapper around
`bsg_fifo_1r1w_small`. The tasks' hidden mutants target the wrapper's stream
protocol, arbitration, and formal-observable behavior, not BaseJump STL
internals.

License: Solderpad Hardware License, Version 0.51.

Copyright notice from the upstream license:

> Copyright 2016 Michael B. Taylor. Copyright and related rights are licensed
> under the Solderpad Hardware License, Version 0.51.

The upstream license text is preserved in each vendored
`vendor/basejump_stl/LICENSE` file.

```

### pyproject.toml

```
[project]
name = "cryobrain"
version = "0.1.0"
description = "CryoBrain — RL environment for neural QEC decoder co-design (HUD v6)"
requires-python = ">=3.11,<3.13"
dependencies = [
    "cocotb==2.0.1",
    "cocotb-bus==0.3.0",
    "cocotb-coverage==2.0",
    "hud-python[agents]>=0.6.5",
    "hypothesis==6.152.7",
    "matplotlib>=3.8",
    "numpy>=1.26",
    "pydantic>=2.0.0",
    "pymatching>=2.0",
    "pyuvm==4.0.1",
    "stim>=1.14",
]

[project.optional-dependencies]
rl = ["modal>=0.67"]
sponsors = [
    "modal>=0.67",
    "exa-py>=1.0",
    "openai>=1.0",
    "python-dotenv>=1.0",
]
# Daytona SDK pulls native wheels; install in Linux/WSL when needed:
#   uv pip install daytona

[dependency-groups]
dev = [
    "pytest>=8",
    "pytest-asyncio>=0.23",
]

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.hatch.build.targets.wheel]
only-include = [
    "env.py",
    "tasks.py",
    "task_catalog.py",
    "grader.py",
    "scenario_helpers.py",
    "cryobrain",
    "tasks",
]

[tool.pytest.ini_options]
asyncio_mode = "auto"
testpaths = ["tests"]
markers = [
    "wsl: requires Linux/WSL EDA toolchain",
]
```

### web/package.json

```
{
  "name": "cryobrains-web",
  "private": true,
  "version": "0.1.0",
  "type": "module",
  "description": "CryoBrains — React scrollytelling app bound to real measured CryoBrain swarm artifacts.",
  "scripts": {
    "dev": "vite",
    "build": "tsc -b && vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "react": "^18.3.1",
    "react-dom": "^18.3.1",
    "three": "^0.169.0",
    "@react-three/fiber": "^8.17.10",
    "@react-three/drei": "^9.114.3"
  },
  "devDependencies": {
    "@types/react": "^18.3.12",
    "@types/react-dom": "^18.3.1",
    "@types/three": "^0.169.0",
    "@vitejs/plugin-react": "^4.3.4",
    "typescript": "^5.6.3",
    "vite": "^5.4.11"
  }
}

```

### web/src/main.tsx

```typescript
import React from "react";
import { createRoot } from "react-dom/client";
import App from "./App";

createRoot(document.getElementById("root")!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
);

```

### web/src/App.tsx

```typescript
import { useCallback, useEffect, useRef, useState } from "react";
import { C } from "./theme";
import { useCryoData } from "./data/useCryoData";
import {
  AGENTS,
  ADOPTION,
  CHIP_SPEC,
  NPU,
  PROOF_FILES,
  WEDGE,
  buildCharts,
  buildSwarmHud,
  type Charts,
} from "./data/derive";
import type { ReplayEvent } from "./data/types";

import { TopNav, DotNav } from "./sections/Nav";
import { GlobalKeyframes } from "./sections/common";
import { S01Hero } from "./sections/S01Hero";
import { S02Problem } from "./sections/S02Problem";
import { S03Npu } from "./sections/S03Npu";
import { S04TwoLoops } from "./sections/S04TwoLoops";
import { S05Built } from "./sections/S05Built";
import { S06Swarm } from "./sections/S06Swarm";
import { S07Evidence } from "./sections/S07Evidence";
import { S08Benchmark } from "./sections/S08Benchmark";
import { S09Pareto } from "./sections/S09Pareto";
import { S10Research } from "./sections/S10Research";
import { S11Memory } from "./sections/S11Memory";
import { S12Chip } from "./sections/S12Chip";
import { S13Business } from "./sections/S13Business";
import { S14Close } from "./sections/S14Close";

const SECTION_COUNT = 14;

export default function App() {
  const { data, error } = useCryoData();
  const rootRef = useRef<HTMLDivElement>(null);
  const [active, setActive] = useState(0);
  const [swarmEvent, setSwarmEvent] = useState<ReplayEvent | null>(null);

  const goTo = useCallback((i: number) => {
    const root = rootRef.current;
    if (!root) return;
    const secs = Array.from(root.querySelectorAll<HTMLElement>("[data-section]"));
    const target = secs[i];
    if (target) root.scrollTo({ top: target.offsetTop, behavior: "smooth" });
  }, []);
  const next = useCallback(() => goTo(Math.min(active + 1, SECTION_COUNT - 1)), [active, goTo]);
  const prev = useCallback(() => goTo(Math.max(active - 1, 0)), [active, goTo]);

  // active-section observer
  useEffect(() => {
    const root = rootRef.current;
    if (!root) return;
    const secs = Array.from(root.querySelectorAll<HTMLElement>("[data-section]"));
    if (!secs.length) return;
    const io = new IntersectionObserver(
      (entries) => {
        entries.forEach((en) => {
          if (en.isIntersecting && en.intersectionRatio > 0.5) {
            const i = secs.indexOf(en.target as HTMLElement);
            if (i >= 0) setActive(i);
          }
        });
      },
      { root, threshold: [0.5] },
    );
    secs.forEach((s) => io.observe(s));
    return () => io.disconnect();
  }, [data]);

  // keyboard nav
  useEffect(() => {
    const onKey = (e: KeyboardEvent) => {
      if (e.key === "ArrowDown" || e.key === "PageDown") {
        e.preventDefault();
        next();
      } else if (e.key === "ArrowUp" || e.key === "PageUp") {
        e.preventDefault();
        prev();
      }
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [next, prev]);

  const charts: Charts | null = data ? buildCharts(data) : null;
  const hud = buildSwarmHud(swarmEvent);

  return (
    <div
      id="cb-root"
      ref={rootRef}
      style={{
        position: "fixed",
        inset: 0,
        overflowY: "scroll",
        scrollSnapType: "y mandatory",
        background: C.bg,
        color: C.ink,
        fontFamily:
          "-apple-system,BlinkMacSystemFont,'SF Pro Display','SF Pro Text','Helvetica Neue',Helvetica,Arial,sans-serif",
        WebkitFontSmoothing: "antialiased",
        lineHeight: 1.5,
        scrollbarWidth: "none",
      }}
    >
      <GlobalKeyframes />
      <TopNav era={data?.meta.data_era ?? "measured"} marathon={data?.marathon} />
      <DotNav active={active} goTo={goTo} count={SECTION_COUNT} />

      <S01Hero next={next} decoder={data?.decoder} />
      <S02Problem />
      <S03Npu npu={NPU} />
      <S04TwoLoops />
      <S05Built agents={AGENTS} proofFiles={PROOF_FILES} />
      <S06Swarm data={data} hud={hud} onEvent={setSwarmEvent} active={active === 5} />
      <S07Evidence charts={charts} decoder={data?.decoder} />
      <S08Benchmark charts={charts} climbFifo={data?.climb.fifo} />
      <S09Pareto charts={charts} pareto={data?.pareto} />
      <S10Research charts={charts} adoption={ADOPTION} />
      <S11Memory charts={charts} marathon={data?.marathon} />
      <S12Chip chipSpec={CHIP_SPEC} />
      <S13Business wedge={WEDGE} />
      <S14Close />

      {error && (
        <div
          style={{
            position: "fixed",
            bottom: 16,
            left: 16,
            zIndex: 99,
            padding: "10px 14px",
            borderRadius: 10,
            background: "rgba(255,69,58,.15)",
            border: "1px solid rgba(255,69,58,.4)",
            color: C.red,
            fontSize: 12,
            fontFamily: "ui-monospace,'SF Mono',Menlo,monospace",
          }}
        >
          data load failed: {error} — expected public/data/cryobrain.json
        </div>
      )}
    </div>
  );
}

```

### tasks.py

```python
"""CryoBrain task bindings for `hud eval tasks.py`."""

from env import cryo_task, env, verilog_task  # noqa: F401
from task_catalog import CRYO_CURRICULUM, TASK_SPECS

tasks = []

for _spec in TASK_SPECS:
    if _spec.template == "cryo_task":
        _curriculum = CRYO_CURRICULUM[_spec.slug]
        _task = cryo_task(
            slug=_spec.slug,
            task_id=_spec.task_id,
            distance=_curriculum["distance"],
            noise_rate=_curriculum["noise_rate"],
            max_latency_cycles=_curriculum["max_latency_cycles"],
            max_area_mm2=_curriculum["max_area_mm2"],
            max_power_mw=_curriculum["max_power_mw"],
        )
    else:
        _task = verilog_task(slug=_spec.slug, task_id=_spec.task_id)

    _task.slug = _spec.slug
    _task.columns = {
        "task_id": _spec.task_id,
        "track": _spec.track,
        "variant": _spec.variant,
        "language": _spec.language,
        "toolchain": _spec.toolchain,
        "module": _spec.module,
    }
    tasks.append(_task)
```

### grader.py

```python
"""Hand-built EvaluationResult that preserves the hidden grader's hard cap."""

import importlib.util
from pathlib import Path
from typing import Any

from hud.graders import EvaluationResult, SubScore  # v6 home (was hud.tools.types)

from scenario_helpers import WORKSPACE_ROOT, hidden_dir as _hidden_dir
from task_catalog import TASK_SPECS_BY_TASK_ID


def _load_grade_module(task_id: str, hidden_dir: Path):
    grade_path = hidden_dir / "grade.py"
    spec = importlib.util.spec_from_file_location(f"{task_id}_hidden_grade", grade_path)
    if spec is None or spec.loader is None:
        raise RuntimeError(f"cannot import hidden grader at {grade_path}")
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module


def _subscores_from_result(result: dict[str, Any]) -> list[SubScore]:
    subscores = []
    for name, data in result.get("subscores", {}).items():
        raw_value = data.get("raw_score")
        if raw_value is None:
            weight = float(data.get("weight", 1.0))
            raw_value = float(data.get("weighted_score", 0.0)) / weight if weight else 0.0
        subscores.append(
            SubScore(
                name=name,
                weight=float(data.get("weight", 0.0)),
                value=max(0.0, min(1.0, float(raw_value or 0.0))),
                metadata=data.get("result"),
            )
        )
    return subscores


def evaluate_task(task_id: str) -> EvaluationResult:
    task_spec = TASK_SPECS_BY_TASK_ID[task_id]
    workdir = WORKSPACE_ROOT
    hidden_dir = _hidden_dir(task_id)
    grade_mod = _load_grade_module(task_id, hidden_dir)
    try:
        result: dict[str, Any] = grade_mod.grade(
            workdir,
            rtl_override=None,
            hidden_root=hidden_dir,
        )
    except Exception as exc:  # noqa: BLE001 - fail closed; never error the episode
        # A missing/renamed editable file or any grader crash must score 0, not raise out
        # and error the rollout: an agent WILL delete the target file, and that should be a
        # 0, not a failed run. (Reproduced: missing props -> FileNotFoundError -> episode error.)
        return EvaluationResult(
            reward=0.0,
            done=True,
            content=f"{task_id}: submission could not be graded ({type(exc).__name__}: {exc})",
            info={
                "task_id": task_id,
                "module": task_spec.module,
                "track": task_spec.track,
                "hard_caps": ["grader_error"],
                "error": f"{type(exc).__name__}: {exc}",
                "workdir": str(workdir),
                "hidden_dir": str(hidden_dir),
            },
            subscores=[],
        )

    # Build EvaluationResult by hand: do NOT route through hud.graders.combine(),
    # which renormalizes positive weights and would erase the grader's hard cap
    # (functional==0 -> reward forced to 0). The negative-weight hard_cap_penalty subscore
    # reconciles the displayed subscores to the capped reward.
    subscores = _subscores_from_result(result)
    weighted_sum = sum(subscore.weight * subscore.value for subscore in subscores)
    reward = float(result.get("reward", 0.0))
    if reward + 1e-9 < weighted_sum:
        subscores.append(
            SubScore(
                name="hard_cap_penalty",
                weight=reward - weighted_sum,
                value=1.0,
                metadata={"hard_caps": result.get("hard_caps", [])},
            )
        )

    return EvaluationResult(
        reward=reward,
        done=True,
        content=f"{task_id} graded",
        info={
            "task_id": task_id,
            "module": task_spec.module,
            "track": task_spec.track,
            "hard_caps": result.get("hard_caps", []),
            "workdir": str(workdir),
            "hidden_dir": str(hidden_dir),
        },
        subscores=subscores,
    )

```

### task_catalog.py

```python
"""CryoBrain + fallback task catalog."""

from dataclasses import dataclass
from pathlib import Path


ROOT_DIR = Path(__file__).resolve().parent
TASK_ROOT = ROOT_DIR / "tasks"


@dataclass(frozen=True)
class TaskSpec:
    task_id: str
    slug: str
    prompt: str
    track: str
    variant: str
    language: str
    module: str
    toolchain: str
    template: str = "cryo_task"


def _prompt(task_id: str) -> str:
    return (TASK_ROOT / task_id / "prompt.md").read_text(encoding="utf-8")


CRYO_BRAIN_DECODER_D3 = TaskSpec(
    task_id="cryo_brain_decoder",
    slug="cryo-brain-decoder-d3",
    prompt=_prompt("cryo_brain_decoder"),
    track="qec-codesign",
    variant="distance_3",
    language="systemverilog+python",
    module="cryo_brain_decoder",
    toolchain="verilator+yosys+stim",
    template="cryo_task",
)

CRYO_BRAIN_DECODER_D5 = TaskSpec(
    task_id="cryo_brain_decoder",
    slug="cryo-brain-decoder-d5",
    prompt=_prompt("cryo_brain_decoder"),
    track="qec-codesign",
    variant="distance_5",
    language="systemverilog+python",
    module="cryo_brain_decoder",
    toolchain="verilator+yosys+stim",
    template="cryo_task",
)

CRYO_BRAIN_DECODER_D7 = TaskSpec(
    task_id="cryo_brain_decoder",
    slug="cryo-brain-decoder-d7",
    prompt=_prompt("cryo_brain_decoder"),
    track="qec-codesign",
    variant="distance_7",
    language="systemverilog+python",
    module="cryo_brain_decoder",
    toolchain="verilator+yosys+stim",
    template="cryo_task",
)

STREAM_ARB_FIFO_REPAIR = TaskSpec(
    task_id="stream_arb_fifo_repair",
    slug="stream-arb-fifo-repair",
    prompt=_prompt("stream_arb_fifo_repair"),
    track="fallback-design",
    variant="repair_debug",
    language="systemverilog",
    module="stream_arb_fifo",
    toolchain="verilator+yosys",
    template="verilog_task",
)

STREAM_ARB_FIFO_COCOTB_DV = TaskSpec(
    task_id="stream_arb_fifo_cocotb_dv",
    slug="stream-arb-fifo-cocotb-dv",
    prompt=_prompt("stream_arb_fifo_cocotb_dv"),
    track="fallback-verification",
    variant="repair_debug",
    language="python+cocotb",
    module="stream_arb_fifo",
    toolchain="cocotb+verilator",
    template="verilog_task",
)

STREAM_ARB_FIFO_FORMAL = TaskSpec(
    task_id="stream_arb_fifo_formal",
    slug="stream-arb-fifo-formal",
    prompt=_prompt("stream_arb_fifo_formal"),
    track="fallback-formal",
    variant="repair_debug",
    language="systemverilog-formal",
    module="stream_arb_fifo",
    toolchain="symbiyosys+yosys",
    template="verilog_task",
)

TASK_SPECS = [
    CRYO_BRAIN_DECODER_D3,
    CRYO_BRAIN_DECODER_D5,
    CRYO_BRAIN_DECODER_D7,
    STREAM_ARB_FIFO_REPAIR,
    STREAM_ARB_FIFO_COCOTB_DV,
    STREAM_ARB_FIFO_FORMAL,
]

# HUD eval binds by slug (6 curriculum/fallback variants). On-disk graders share task_id.
TASK_SPECS_BY_SLUG = {spec.slug: spec for spec in TASK_SPECS}

# One metadata row per filesystem task directory (4 on-disk tasks).
TASK_SPECS_BY_TASK_ID: dict[str, TaskSpec] = {}
for _spec in TASK_SPECS:
    TASK_SPECS_BY_TASK_ID.setdefault(_spec.task_id, _spec)

# Back-compat alias used by grader/setup (filesystem task_id, not eval slug).
TASK_SPECS_BY_ID = TASK_SPECS_BY_TASK_ID

# RSI distance curriculum bindings (SPEC F7 / CP6)
CRYO_CURRICULUM = {
    "cryo-brain-decoder-d3": {
        "distance": 3,
        "noise_rate": 0.001,
        "max_latency_cycles": 64,
        "max_area_mm2": 0.06,
        "max_power_mw": 8.0,
    },
    "cryo-brain-decoder-d5": {
        "distance": 5,
        "noise_rate": 0.002,
        "max_latency_cycles": 96,
        "max_area_mm2": 0.08,
        "max_power_mw": 10.0,
    },
    "cryo-brain-decoder-d7": {
        "distance": 7,
        "noise_rate": 0.003,
        "max_latency_cycles": 128,
        "max_area_mm2": 0.10,
        "max_power_mw": 12.0,
    },
}

CRYO_SLUGS = tuple(CRYO_CURRICULUM)
FALLBACK_SLUGS = tuple(
    spec.slug for spec in TASK_SPECS if spec.track.startswith("fallback")
)


def curriculum_for_slug(slug: str) -> dict[str, float | int]:
    """Return RSI distance/noise/budget knobs for a cryo eval slug."""
    return dict(CRYO_CURRICULUM[slug])
```

### scenario_helpers.py

```python
"""Per-task workspace setup for CryoBrain + fallback tracks."""

import json
import os
import shutil
import tempfile
from pathlib import Path

ROOT_DIR = Path(__file__).resolve().parent
LOCAL_TASK_ROOT = ROOT_DIR / "tasks"
HIDDEN_ROOT = Path(os.environ.get("HIDDEN_ROOT", "/donotaccess"))
AGENT_USER = "agent"
AGENT_GROUP = "agent"

AGENT_FILES = (
    "Makefile",
    "filelist.f",
    "prompt.md",
    "rtl",
    "dv",
    "synth",
    "scripts",
    "formal",
    "vendor",
    "design_config.json",
    "scenario.json",
)
_KEEP = {".hud"}

GOLDEN_OVERLAY = {
    "stream_arb_fifo_repair": ("stream_arb_fifo_golden.sv", "rtl/stream_arb_fifo.sv"),
    "stream_arb_fifo_cocotb_dv": ("solution/test_stream_arb_fifo.py", "dv/cocotb/test_stream_arb_fifo.py"),
    "stream_arb_fifo_formal": ("solution/stream_arb_fifo_props.sv", "formal/stream_arb_fifo_props.sv"),
    "cryo_brain_decoder": ("cryo_brain_decoder_golden.sv", "rtl/cryo_brain_decoder.sv"),
}


def _resolve_workspace_root() -> Path:
    explicit = os.environ.get("WORKSPACE_ROOT")
    if explicit:
        return Path(explicit)
    if Path("/workdir").is_dir():
        return Path("/workdir")
    root = Path(tempfile.gettempdir()) / "hud-cryobrain" / f"workdir-{os.getpid()}"
    root.mkdir(parents=True, exist_ok=True)
    return root


WORKSPACE_ROOT = _resolve_workspace_root()


def hidden_dir(task_id: str) -> Path:
    candidate = HIDDEN_ROOT / task_id
    if candidate.is_dir():
        return candidate
    return LOCAL_TASK_ROOT / task_id / "donotaccess"


def write_scenario_files(workdir: Path, scenario: dict[str, object]) -> None:
    """Bind curriculum distance/noise/budget into agent-visible scenario.json."""
    scenario_path = workdir / "scenario.json"
    base = {}
    if scenario_path.is_file():
        base = json.loads(scenario_path.read_text(encoding="utf-8"))
    base.update(scenario)
    scenario_path.write_text(json.dumps(base, indent=2), encoding="utf-8")


def _is_root() -> bool:
    return hasattr(os, "geteuid") and os.geteuid() == 0


def _make_agent_writable(path: Path) -> None:
    if not _is_root():
        return
    for item in [path, *path.rglob("*")]:
        if item.name in _KEEP:
            continue
        try:
            shutil.chown(item, user=AGENT_USER, group=AGENT_GROUP)
            item.chmod(0o755 if item.is_dir() else 0o644)
        except (LookupError, PermissionError, FileNotFoundError):
            pass


def _clear_workspace(workdir: Path) -> None:
    for child in workdir.iterdir():
        if child.name in _KEEP:
            continue
        if child.is_dir() and not child.is_symlink():
            shutil.rmtree(child, ignore_errors=True)
        else:
            child.unlink(missing_ok=True)


def _copy_into(src: Path, dst: Path) -> None:
    for item in src.iterdir():
        target = dst / item.name
        if item.is_dir():
            shutil.copytree(item, target, symlinks=True, dirs_exist_ok=True)
        else:
            shutil.copy2(item, target)


def _populate_from_repo(task_id: str, workdir: Path) -> None:
    src = LOCAL_TASK_ROOT / task_id
    for name in AGENT_FILES:
        item = src / name
        if not item.exists():
            continue
        target = workdir / name
        if item.is_dir():
            shutil.copytree(item, target, ignore=shutil.ignore_patterns("__pycache__"), dirs_exist_ok=True)
        else:
            shutil.copy2(item, target)
    calib = workdir / "scripts" / "check_calibration.py"
    if calib.is_file():
        calib.unlink(missing_ok=True)


def setup_task(
    task_id: str,
    validate_mode: str | None = None,
    scenario: dict[str, object] | None = None,
) -> dict[str, object]:
    workdir = WORKSPACE_ROOT
    hidden = hidden_dir(task_id)
    baked_baseline = HIDDEN_ROOT / task_id / "baseline"

    workdir.mkdir(parents=True, exist_ok=True)
    _clear_workspace(workdir)
    if baked_baseline.is_dir():
        _copy_into(baked_baseline, workdir)
    else:
        _populate_from_repo(task_id, workdir)

    if scenario:
        write_scenario_files(workdir, scenario)

    if validate_mode == "golden_pass" and task_id in GOLDEN_OVERLAY:
        src_rel, dst_rel = GOLDEN_OVERLAY[task_id]
        src = hidden / src_rel
        dst = workdir / dst_rel
        if src.is_file():
            dst.parent.mkdir(parents=True, exist_ok=True)
            shutil.copy2(src, dst)

    _make_agent_writable(workdir)

    return {
        "success": workdir.is_dir(),
        "task_id": task_id,
        "workdir": str(workdir),
        "hidden_dir": str(hidden),
        "validate_mode": validate_mode,
        "scenario": scenario,
        "baseline_reset": True,
    }
```

[510 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]