Skip to content

Modernization roadmap

This page summarizes the modernization design that produced this documentation site and the run / doctor / tutorial / namelist additions. The full dossier — including the persona-validated reviews — lives in the repository under docs/modernization/.

nwp-compose is technically mature, but a persistent last-mile gap stands between “I have a workflow.yaml” and “my forecast is cycling”: the path is multi-step, assumes Cylc fluency, and several checks fail silently. The project’s own persona reviews surfaced the same five themes across every phase:

  1. cylc validate passing ≠ runnable;
  2. warnings that emit but don’t block;
  3. docs that drift from code;
  4. the gap between generate and “ready to run” (with <workflow_id> undefined);
  5. demo/banner copy overstating capability.

A scientist migrating off a personal bash/cron setup hits themes 1, 4, and 5 on their first afternoon. So the design’s spine is one sentence: lower the Cylc-fluency barrier and make the last mile a guided, honest, gated, single-command experience — without elevation, on any shared system.

  • Unprivileged-everywhere — no sudo, no system services, no Docker daemon; $XDG-aware, redirectable state; rootless containers; user crontab.
  • Additive only — the v0 schema is frozen; everything is a new command, doc, or optional parameter. The freeze test stays green.
  • Honor code-gen resistance — shell out to Cylc, drive the existing namelist/render primitives; no Python flow_builder.
  • Generate docs from code — the CLI reference is introspected from the live Click app, so a drifted doc is a failing build, not a stale page.
  • Gate, don’t just warn — every new path that produces a runnable artifact routes through the same validate/unphysical-block gate.

Ranked, each unprivileged-aware (no recommendation requires elevation):

#RecommendationWhyEffort
1Commit a dependency lockfile (uv.lock)cylc-flow’s 30+ transitive deps are unpinned today — the highest-value supply-chain win.low
2Vite build for gui/app/Retires the ~1.5 MB in-browser Babel transpile and the dev-build React; enables tree-shaking and production builds. Runs entirely as the developer’s user.medium
3SRI on every CDN loadThe Pyodide and reveal.js loads lack integrity hashes; add them or self-host.low
4CSP at the Caddy edgeDefense-in-depth beyond tag-level SRI for the hosted GUI.low
5Rootless container recipesApptainer/Podman defs so the CI harness and any container path run without a Docker daemon on HPC.medium
6XDG-aware state pathsXDG_CACHE_HOME/XDG_DATA_HOME/CYLC_RUN_DIR honored everywhere (see the unprivileged checklist).low

Following the repository’s sci-plan → sci-review / eng-plan → eng-review convention, the design was validated by two adversarial personas — a senior scientist/modeler and a senior research software engineer. Their reviews (in docs/modernization/51-sci-review.md and 52-eng-review.md) caught real correctness bugs in the draft specs — e.g. that MPAS CFL is the non-blocking W5, not a blocking code, and that several components declare namelist templates that are not shipped — which were folded back into these docs. That is the review loop working as intended.