# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## What this repository is ALLSHIFT is Team SHIFT's single shared repository (TU/e student team; an AI-managed hospital hydrogen microgrid, Beth Israel Deaconess Boston as the case). It is public on Gitea (`git.teamshiftenergy.com/pepe/ALLSHIFT`). Four kinds of content live side by side: - `docs/` — the documentation hub. Every project document exists here as a markdown report; `docs/README.md` is the index and ends with the project-wide open-questions list. Retired material goes to `superseded/` with a stated reason. - `Shift Matlab Drive/` — a mirror of the team's MATLAB Drive: Simulink models and raw data. The Simulink work belongs to the Simulations cluster (see `docs/04-simulations/simulink-model-inventory.md`; the live framework needs R2026a). No Python goes here. - `website/` — the public Astro site, with its own `website/CLAUDE.md` and `pnpm` commands. No Python goes here either. - Root `pyproject.toml` + `uv.lock` — the one pinned Python environment for every cluster. Cluster code lives in top-level folders registered as uv workspace members; `AICONTROL/` (AI & Control cluster) is the first. ## Commands (from the repository root) ```bash uv sync # create/refresh .venv from uv.lock (Python 3.12; ~1.3 GB, torch included) uv run pytest # all tests (pytest testpaths = AICONTROL/tests) uv run pytest AICONTROL/tests/test_spaces.py::test_action_space_and_shedding_level # one test uv run python -m aicontrol.env.spaces # print the current observation/action layout as a table uv lock # after editing dependencies; commit the updated uv.lock ``` Adding a dependency: edit `dependencies` in the root `pyproject.toml`, run `uv lock`, commit `uv.lock`. Adding a cluster folder: give it its own `pyproject.toml` (hatchling, `packages = [...]`), add the folder to `[tool.uv.workspace] members`, and add its package name to the root `dependencies` and to `[tool.uv.sources]` as `{ workspace = true }`. Website: `cd website && pnpm dev | pnpm build | pnpm preview` — details in `website/CLAUDE.md`. ## Architecture ### Clusters and the three handovers The team leader's *Project Manual* (not in the repo) fixes four clusters and exactly three written handovers between them: 1. **Energy Management → Simulations:** the Parameter Book (a spreadsheet of every rating and efficiency, versioned) and the clean 5-minute BIDMC dataset with Tier 1 / 2 / 3 load assigned, as Parquet. 2. **Simulations → AI:** a Gymnasium environment. Simulations owns everything inside `step()` — the twin's physics, the KPI calculator, and the benchmark controllers (rule-based, MPC on forecasts, perfect knowledge; Pyomo + HiGHS). AI owns everything outside it: the agent, the safety layer, evaluation, dashboard. Written jointly early in Q2, frozen before Christmas. 3. **AI → Business:** one results file, one row per controller × scenario × run, Parquet with a CSV beside it. Fixed by the manual, not up for local decision: 5-minute timestep (105,120 steps per year); a full simulated year must run in under a minute; Boston with ISO New England prices and carbon; Tier 1 load is never shed; reward weights are agreed across clusters and never tuned by code. ### `AICONTROL/` — the AI & Control cluster package - Everything is built from `AICONTROL/configs/env.yaml`, so the joint session with Simulations can change a number without touching code. Values marked `PLACEHOLDER` there (plant sizes, load bound, reward weights) are stand-ins owned by other clusters; keep the marker until the owning cluster confirms a value. - `aicontrol/env/spaces.py` is the single source of the interface shape. `observation_slots(cfg)` defines the flat 64-value observation in order (calendar 4, present-state 12, forecasts = quantities × horizons × quantiles = 48); `build_action_space` gives a `Box(4)`: `u_ele` [0, 1], `u_fc` [0, 1], `u_batt` [−1, 1] with positive = discharge, `shed` [0, 2] rounded by `shedding_level()` because Stable-Baselines3 cannot mix continuous and discrete actions. Names follow the Simulator I/O sheet (`P_PV`, `SoC`, `H2_level`, `p_tank`, `price`, `CO2_int`, `grid_on`). - `AICONTROL/docs/interface-draft.md` is the handover document; keep its tables in step with `spaces.py` (regenerate the observation table with `describe()`). - The placeholder environment (next: `aicontrol/env/placeholder.py`) exposes exactly these spaces with toy physics. It never gets better physics and is deleted the day the twin runs. Do not build a competing simulator in this folder. - Planned subpackages: `forecast/`, `train/`, `evaluate/`, `safety/`, `dashboard/`. Tooling is fixed by the manual: LightGBM / scikit-learn / Optuna for forecasting, Gymnasium + Stable-Baselines3 for RL, Weights & Biases for logging (not MLflow), SHAP + Streamlit. ### Documentation conventions - A markdown report of a non-markdown source opens with a provenance table (Source, Format, MD5, Status, Report generated). Reconstructed tables are labelled as such; observations that go beyond the source are attributed to the audit, not the author. - `docs/02-specifications/` is owned by the AI cluster. The RL state / action / reward documents there are superseded by the manual's interface list but kept for the rationale behind individual terms. - `docs/01-project/ai-control-cluster-plan-2026-2027.md` is the AI cluster's plan: seats, Q1 week by week, later blocks, open items for the leader. ## Data: what actually exists Under `Shift Matlab Drive/Shift Matlab Drive/Energy_Managment/`: hospital load is the NREL ComStock building `89993-0.parquet` (2018, 15-minute, simulated; `MA_hourly_load.csv` is a mis-named numerical twin of it). Weather is NSRDB 2019, hourly, timestamps in UTC. PV is a PVWatts 4 kW typical-year run that aligns with neither. There is no price, carbon-intensity, outage or measured-load series. `hospital_communication_energy_system.csv` is synthetic noise; derive nothing from it. Provenance and licences: `docs/06-data/dataset-inventory.md`. ## Things to know - Formats: machine-made tables are Parquet, hand-written settings are YAML, documents are Markdown. - `.venv/`, `wandb/` run folders and `**/data/raw/` are gitignored; `uv sync` rebuilds the environment from `uv.lock` on any machine. - `website/CLAUDE.md` embeds live third-party keys that are due for rotation; do not copy them anywhere. - `Interview Questions-*.md` at the root is personal recruitment data, gitignored on purpose.