RFCs & Design Notes
Design proposals and extensions for the ESM Format.
Design proposals, extensions, and verification reports for the ESM Format.
- Ast expression templates
- Canonical number form typed fields
- Closed function registry
- Coupling libraries role binding
- Dae binding strategies
- Discretization review v2.1 verification
- Discretization status
- Discretization
- Match pattern scoping constraints
- Multi output discretizations draft
- Open op namespace fixpoint rewrite
- Out of line expression templates
- Portable data source urls
- Rust diffsol solver guard gap
- Sampled tables
- Scoped template injection
- Self join two ranges over one index set
- Template import renaming
- Template library imports
- A semiring-parameterized FAQ IR for ESS arrayops
Concrete proposal to generalize the ESS arrayop node into a Functional-Aggregate-Query IR over semirings — unifying tensor contraction (ESM/ESD discretization), relational select-multiply-aggregate (ESI), and the data-dependent index-set construction (mesh topology) that currently must live in imperative grid code.
- A top-level `solver` block: numerics the document knows about itself
An optional, top-level, purely advisory `solver` block carrying stiffness, integration tolerances, and a splitting hint — facts about the model that every binding independently needs and none can derive cheaply. Advisory governs the mechanism, never the outcome: a binding that ignores every field and still converges conforms; one that ignores them and hangs does not. Not an algorithm name, not a compile knob, not part of the flattened IR.
- Analyses (§6.7): settling the semantics an executor would need
esm-spec §6.7 specifies the shape of an analysis but not its meaning. Exactly one construct — Cartesian sweep enumeration — is implementable against the text today; the output time grid, the four time reductions, off-grid sampling, plot behavior under a sweep, sweep-point ordering, override-key resolution, pinned_coords' coordinate space, the output contract, and failure handling are all undefined, and each of them changes output bytes. This RFC proposes a ruling for each. Fourteen items: twelve are prose-only, one is a schema description touch, one is an optional schema addition that can wait. It settles meaning; it does not schedule an executor.
- Causal self-reference along an index axis
- Mount-edge index-set renaming
An opt-in `index_set_rename` on a component mount edge, so one document can mount two components that use the same axis name at different lengths.
- Pure-I/O data loaders: separating read-from-disk from regridding and reprojection
Strip the data loader down to a single responsibility — read/update a slice of data from disk — by moving regridding (value transfer) and reprojection (coordinate transform) out of the loader and into a model component built from existing ESD pieces. The loader's native grid is expressed once, in the shared GDD Grid format; its variables seed the cadence partition as discrete (or const). A pure-I/O loader is then a model subsystem and a single-component file becomes externally referenceable, closing the loader-reuse gap (ESS issue #24).
- Renaming the `aggregate` node to `faq`
The unified query node is renamed from `aggregate` to `faq` (Functional Aggregate Query) at esm 1.1.0. `aggregate` becomes a deprecated alias, normalized on load with a warning and removed at 2.0.0. The `arrayop` alias — declared removed at 0.8.0 but still live in all five bindings — is removed for real.
- Streaming output sinks: incremental simulation output to disk (Zarr), checkpoint/restart, and CF coordinates
Add an output boundary that mirrors the pure-I/O data-loader input seam. A cadence-driven Sink streams simulation state to disk incrementally instead of accumulating the whole trajectory in RAM, so runs whose results do not fit in memory become possible. Zarr is the first backend (cloud- and HPC-native, chunk-as-object). The write path lives in EarthSciIO behind a Writer registry symmetric to the read registries; EarthSciAST exposes a build_output_callback + Sink protocol symmetric to build_refresh_callback + the Provider protocol; the solver stays user-owned (library-exposes-rhs-not-solver). Includes checkpoint/restart, an additive CF coordinate-role schema delta that also covers unstructured and curvilinear grids, multi-grid coupled-component output, and cross-language parity (Julia/Python/Rust) gated by a shared conformance corpus.
- The unified variable model: two declared types, everything else derived
Collapse the five declared variable types (state, parameter, observed, brownian, discrete), the separate data-loader component kind, and the discrete_parameters event list into exactly two declared types — unknown and parameter. An unknown's behavior is given by equations; a parameter carries a value or distribution and an optional update block. ODE-state-ness, observed-ness, noise, and refresh cadence all become derived classifications that every binding computes with the same functions.