# ADR-0007: `platform` plugin type isolates HPC job submission from science code

| Field         | Value       |
|---------------|-------------|
| Kind          | ADR         |
| Status        | Accepted    |
| Decided       | historical  |
| Deciders      | Antoine Berchet |
| Supersedes    | —           |
| Superseded by | —           |

## Context

CIF runs across many different clusters at partner institutions — TGCC/CCRT (CEA),
Jean Zay (IDRIS), ECMWF ECS, Empa Daint, LSCE Obelix, FMI Puhti, LAERO Nuwa, plus
Docker-based local/CI environments, several with NVIDIA/AMD GPU variants
(`pycif/plugins/platforms/` lists 12+ such plugins). Each cluster has its own batch
scheduler and commands (e.g. TGCC-CCRT submits via `ccc_msub` and monitors via
`ccc_mpp`), its own environment-module system, and its own account / project / partition
conventions. Without an abstraction, every mode that launches sub-jobs (variational,
ensemble/EnSRF, analytic) would need to embed cluster-specific submission logic itself.

## Decision

We isolate all of that behind a `platform` plugin type (`Platform(Plugin)` in
[`pycif/utils/classes/platforms.py`](https://gitlab.in2p3.fr/satinv/cif/-/blob/devel/pycif/utils/classes/platforms.py)),
with `submit_job` / `check_jobs` as the interface contract every concrete platform
overrides. One plugin per cluster (`pycif/plugins/platforms/<cluster>/`) encapsulates
that cluster's job templates, environment modules, and batch-system commands; the rest
of CIF calls only the generic `submit_job` / `check_jobs` interface.

## Consequences

- Porting CIF to a new cluster means writing one platform plugin, not auditing every
  mode that submits jobs.
- `Platform.submit_job`'s default implementation falls back to a local subprocess, so a
  platform plugin only needs to override what's actually cluster-specific.
- Cluster quirks (module lists, partition names, project IDs, GPU variants) live in one
  directory per cluster rather than as scattered conditionals in the science code.
- A newcomer who doesn't know this exists won't understand why every YAML config has a
  `platform:` block, or why there are 12+ near-identical-looking directories under
  `pycif/plugins/platforms/`.
