Repository navigation
Releases: EarthSciML/EarthSciAST
Release list
v0.8.0
EarthSciAST v0.8.0
A breaking release: flatten writes a pointwise-lifted state differently. The .esm format stays at esm 1.3.0, and every document that loaded under 0.7.0 loads unchanged.
Breaking changes
-
A pointwise-lifted state names its index sets (esm-libraries-spec §4.7.5, "Pointwise lift: index sets"). When
flattenlifts a scalar state onto an operator's grid (esm-spec §10.5), every binding now records the same three things:- The lifted state's
shapeinstate_variablesis the grid's index sets, such as["lon", "lat"]. Python, Rust, TypeScript and Go used to leave the shape empty. Julia already wrote one. - Both lifted
faqnodes range each loop over its index set,{"from": "lon"}, printedi in lon. Python, Rust, TypeScript and Go used to write the interval[1, 4]. lifted_shapesis unchanged: it still holds the extents, now the sizes of the index sets in the state'sshape.
Each dimension's index set is the one an operand gathered at the lift's loops is declared on, else the only declared index set of the dimension's size. When neither decides, the dimension gets a synthetic interval
_liftdim<d>_<extent>, which the flattenedindex_setsgains. Julia used to give such a dimension that name in the shape without adding it toindex_sets, and ranged it as an interval. A document that declares an index set of that name with a different size is now refused with the binding's dimension-promotion error. Code that read a liftedfaq's ranges as intervals, or that recovered a lifted state's index sets by matching extents against other variables' shapes, should read the state'sshapeinstead. Thepointwise_lifttier oftests/conformance/flatten/cases.jsonpins the result in all five bindings. - The lifted state's
-
A state that already has a shape is no longer lifted. Python, Rust, TypeScript and Go lifted every state whose merged equation carried an operator
makearray, so a state already declared on a grid had its equation wrapped in a secondfaqand, with the change above, its declaredshapereplaced. Like Julia, they now leave such a state as merged, with its declared shape and nolifted_shapesentry. -
Two initial conditions for one state are refused. When a state ends up with two
ic(x)equations after coupling (its own and an operator'sic(_var), or two such templates),flattennow raisesConflictingDerivativeErrorin every binding. Before,field_icsheld both entries and whichever a consumer applied last won. -
Rust:
FlattenError::ConflictingDerivativecarries amessage. The variant is now{ species, message }, because it is raised for two kinds of conflict. Code that builds the variant, or matches{ species }without.., must be updated.
Other changes
- Julia: an operator's
ic(_var)gives every state its own initial condition. Anoperator_composeoperator that writesic(_var) ~ eis now expanded once per state, asD(_var)already was, sofield_icsholds one entry per state (esm-libraries-spec §4.7.1 step 3). Julia used to record one entry under_var, so a consumer that writes initial conditions fromfield_icsbuilt a different initial state from Julia than from the other bindings, which already expanded it.
Breaking changes
- feat(flatten)!: a pointwise-lifted state names its index sets (527c343)
Changelog
- chore(release): v0.8.0 (c495252)
- fix(flatten): address PR #623 review findings (916d5a5)
- fix(julia): expand an operator's ic(_var) once per state in flatten (82c4858)
- feat(flatten)!: a pointwise-lifted state names its index sets (527c343)
- test(julia): take the smallest of several samples in the tile allocation check (4ed2c36)
- fix(formal): inventory the two MUSTs of the mounted data-source merge rule (e35fec2)
Installation
using Pkg; Pkg.add("EarthSciAST") # Julia
npm install @earthsciml/ast # TypeScript
pip install earthsci-ast # Python
cargo add earthsci-ast # Rust
go get github.com/EarthSciML/EarthSciAST/pkg/earthsci-ast-go
Command-line tools: esm and esm-narrative
curl -sSL https://github.com/EarthSciML/EarthSciAST/releases/latest/download/update.sh | bashOr download an archive, extract it and run install.sh (install.bat on Windows):
v0.7.0
EarthSciAST v0.7.0
A breaking release: the units checker and the load-time checks are stricter, one error code is renamed, and the minimum Go, Python and Node versions go up. The .esm format stays at esm 1.3.0. Most documents that loaded under 0.6.0 still load unchanged (every file under tests/valid, lib/ and tests/conformance does), but some no longer load. These are documents with a unit error that some bindings used to miss, a broken function table the document never looks up, a unit string that breaks the §4.8.2 grammar, or a newer file that mounts an older one using a construct the older version lacks. The breaking changes below list each case. Many more documents now load with a new warning, units_dimensionless_literal_mismatch, which warns about a rule the next major esm version will enforce. One addition to the 1.3.0 schema, url_substitutions on a mount edge (#618), arrives without a version bump, so a document that uses it does not load under 0.6.0.
Breaking changes
-
New unit warnings on documents that are still valid (#575). A bare numeric literal (or a
constwith nounits) will become dimensionless in the next major esm version. Today it takes on its neighbours' unit. Every binding now types each equation, initialization equation, constraint and reaction rate under both rules, and where only the new rule finds a mismatch it addsunits_dimensionless_literal_mismatchtounit_warnings. Each warning comes with the JSON pointer and theconst(…, units "…")repair.T - 273.15withTin K is one example. Zero in any spelling stays neutral. Errors andis_validdo not change, and a failure inside the warning pass becomes one warning, never an error.scripts/codemod-dimensionless-literals.pyproposes the repairs (#586). -
Two unit-checker fixes make some documents invalid with no warning first (#575). Both bring the bindings into line with the spec and with each other:
ic(x)carriesx's unit in Go, TypeScript and Julia, as it already did in Python and Rust.ic(T [K]) = p0 [Pa]is now aunit_inconsistencyeverywhere.- An undeclared
tis in seconds in Go, TypeScript, Julia and Python, as it already was in Rust (§4.9.1). A model that leavestundeclared and writessin(t)orexp(-t)is now an error. - Also: the "no time unit can reconcile the two sides" derivative check now counts toward a site's verdict, and Julia types a template-invocation rate through its expansion.
-
Version gates read each file's own
esm(#584, esm-spec §4.7). Go, Julia and Rust used to apply the gates to the resolved document, judged against the root's version. Now:- A file that declares 1.1.0 or 1.2.0 and mounts a 1.0.0 file is rejected if that 1.0.0 file carries a unit-bearing
const(const_units_version_too_old) or a top-levelsolverblock (solver_version_too_old). Go, Julia and Rust used to accept this. - In Go, a 1.0.0 root that uses
faqno longer escapesfaq_version_too_oldby mounting something. - The other direction now loads: a 1.0.0 file may mount a 1.2.0 file that uses unit-bearing
const. - Every gate except
faq_version_too_oldreads the declared version as raised by theaggregatenormalization (the 1.1.0 floor). Thesolver.externalandsolver.time_spangates still apply to the root only.
- A file that declares 1.1.0 or 1.2.0 and mounts a 1.0.0 file is rejected if that 1.0.0 file carries a unit-bearing
-
Julia's angle checks match the other bindings (#584).
radagainstsr, andm*radagainstm, are now unit mismatches in Julia. Julia used to accept them. -
Function-table and closed-function checks run at load, on every table (#585, esm-spec §9.2, §9.5.5). All five bindings used to raise these at build or evaluation time, and only for tables a lookup used. Now
validate()and load reject a broken table even when nothing looks it up, with the ten table checks in one pinned order. New codes:table_axis_too_short,table_axis_duplicate_name,table_axis_non_monotonic,table_data_nan,table_outputs_duplicate_name,table_outputs_length_mismatch,table_lookup_args_nonempty(atable_lookupwith a non-emptyargs),interp_axis_not_const,interp_table_not_constandenum_duplicate_value(TypeScript and Go used to accept duplicate enum values silently). -
The error code
searchsorted_nan_in_tableis nowsearchsorted_nanin all five bindings (#585). The registry constants are renamed to match:SEARCHSORTED_NANin Julia, Python, Rust and TypeScript, andCodeSearchsortedNaNin Go. Each binding used to give asearchsortedtable that is not aconstarray a different code. Every binding now raisesinterp_axis_not_const, checked before NaN and monotonicity. -
The unit-string grammar is strict in every binding (#585, esm-spec §4.8.2). Strings that some bindings accepted are now rejected:
- a whitespace-only string (only
""is dimensionless); - a
+sign on an exponent (m^+2), a parenthesized or chained exponent (m^(-2),m^2^3), orm^1e3; 01or1.0in place of the atom1;- a run of letters and digits that is not a registered symbol, such as
s1,kgmorcm3; - a lone
°(Python).
Rust's SI-prefix fallback for symbols missing from the registry is gone, and TypeScript and Julia now read
%has%timesh. - a whitespace-only string (only
-
Some
datetime.*,table_lookupandinterpresults change (#585):datetime.*: fractional times floor toward −∞ in every binding. Python used to round to the microsecond and failed outside years 1–9999, Go rounded to the nanosecond, Julia truncated toward zero, and TypeScript got every date before year 0 wrong. Rust no longer reports hour 24 or wraps an Int32 year.- Overflow: a NaN or infinite time, or a year outside Int32, raises
closed_function_overflowfrom everydatetime.*function. julian_day: now the standard Julian Date everywhere. This changes results only before −4800-03-01.nearesttable lookups: they now return the true nearest knot, with ties going to the lower knot and the ends clamped. The old lowering was wrong in every binding.table_lookupoutputs: an omittedoutputmeans 0, and a single-output table lowers with its wholedata.
-
NaN propagates through
maxandminreductions in Python and Rust (#615), as esm-spec §4.2 requires and Julia already did. Python used to let the first term seed the fold, and Rust skipped NaN, including in its elementwisemax/min. -
Higher minimum toolchains (#599):
- Go:
go.moddeclaresgo 1.26.go-playground/validatorand allgolang.org/x/*modules are no longer dependencies. - Python:
earthsci-astrequires Python 3.11 or later. - TypeScript: the package needs Node 22 or later.
- Go:
-
Rust
ProblemOptionshas a new public field,retain_data_fields(#617). Code that buildsProblemOptionsas a struct literal without..Default::default()must add it.
Other changes
- Mount-edge
url_substitutions(#618, esm-spec §4.7), in all five bindings. A{ref}mount edge can now bind the bare{name}placeholders in the referenced document'sdata_sourceslocations, so many run documents can mount one shared data catalogue, each pointing it at its own data directory. A key that names no placeholder isurl_substitution_unknown_name. A value that is not a string, or that contains{,},?or#, isdata_source_url_unresolved. Related changes in the same PR:- A mounted document's
data_sourcesnow merge into the mounting document at both mount forms in every binding. Before, Python, TypeScript and Go never merged them, Rust merged only at the top-levelmodels.<k>form, and Julia merged only on its native walk. The mounting document's own entry wins a name clash. If two mounts contribute the same source name with different entries, loading fails with the new codedata_source_merge_conflict. - An edge's
bindingsreach through an assembly to a metaparameter that only a document further down the mount tree declares. This used to betemplate_import_unknown_name. - A relative location in a document loaded from a URL joins onto that URL's directory by RFC 3986 in every binding. Python and TypeScript used to produce a meaningless
file://path. - Julia: a mounted file's relative
data_sourcesresolve against that file's directory, not the root's. Two sibling edges that mount the same file are no longer reported as a circular reference.resolve_subsystem_refs!returns the resolvedEsmFile, which carries the merged sources when the root declared none; use the return value.
- A mounted document's
- Rust builds an ingesting document that holds several models (#616). A document with a
kind: "data"parameter, or a caller passingbuild_providersorconst_arrays, used to fail with "document holds several models; pass model_name" when it held more than one model. With nomodel_name, the whole document now builds as one dot-namespaced system, as the non-ingesting routes and the Python and Juliaesm_problemalready did, andesm testpasses on such documents. In such a build, a bare override, provider orconst_arrayskey that matches parameters in more than one model is an error that lists the full names to use. A gated provider for a parameter inside a mounted subsystem now binds underLeaf.sr; it used to bind undersr, where nothing read it. An explicitmodel_name(esm simulate --model) still builds that model alone. - Rust: a data-fed parameter can be asserted and observed like a computed variable (#617). Inline tests and
esm simulate --observedcan name one, andobserved_fieldreturns its ingested values whenProblemOptions::retain_data_fieldsnames it. A fix in the same PR: in a document with differential equations, the right-hand side used to read such a parameter'sdefault(often 0) instead of the ingested data. - **Rust: a data-fed or precision-declaring ...
v0.6.0
EarthSciAST v0.6.0
A breaking release: the expression tree a reaction system lowers to changed shape in four bindings (#572). The .esm format stays at esm 1.3.0, and every document that loaded under 0.5.0 loads unchanged. Lowered equations evaluate to the same numbers as before; what changed is the tree, which esm-libraries-spec §4.6.2 now fixes exactly so that every binding writes the same bytes.
Breaking changes
- The tree
derive_odesandflattenbuild for a reaction system (#572). Every binding now emits the §4.6.2 form, pinned bytests/conformance/reactions/lowering_form.json. The rate law is one n-ary*with the rate first (k * A * B), each species' term is the bare rate law for a net coefficient of 1 andc * rateotherwise, withcan integer literal when it is integral, and several terms form one n-ary+. A loss of 1 is-1 * rate. Code that pattern-matches lowered equations, or compares them to stored trees or strings, needs updating:- Python, Go and TypeScript
flatten: products and sums are no longer nested two operands at a time, and a literal1rate is kept (1 * A, notA). - Rust: integral coefficients are
Expr::Integer, notExpr::Number(Expr::Integer(-1)where 0.5.0 hadExpr::Number(-1.0)). - Julia and TypeScript
deriveOdes: a loss of 1 is-1 * rate, not a unary minus. Julia writes integral coefficients as integer literals (-2, not-2.0). - A species listed more than once on one side of a reaction gets one rate-law factor per entry (
A + Agivesk * A * Aand coefficient-2). Python used to keep only the last entry for that species. - An integral coefficient or exponent is an integer literal only when it is representable in Int64; larger values stay floats in every binding.
- Python, Go and TypeScript
- TypeScript
deriveOdes(#572) no longer emitsD(X, t) = 0for a species no reaction changes; such a species gets no equation, as esm-libraries-spec §4.6.1 requires and the other bindings already did. It also now throws anEsmDiagnosticErrorwith codeundefined_speciesfor a substrate or product the system does not declare, where it used to drop it silently.
Other changes
- Python
Reactiongainssubstrate_entriesandproduct_entries, the entries in listed order with repeats kept (#572). Thereactants/productsmaps now sum a repeated species' coefficients instead of keeping the last one. - Julia accepts SciMLBase 3 alongside SciMLBase 2 (#571), and the OrdinaryDiffEq solver packages at 2.x. ModelingToolkitBase is held at
1 - 1.42, because the ModelingToolkit extension does not yet work with later releases. Callers ofEnsembleProblem(prob, rewrite)must writerewritefor the SciMLBase they load:(prob, i, repeat)under 2,(prob, ctx)under 3. - Julia works with JSONSchema.jl 1.6 (#572), which changed an internal function EarthSciAST's schema validator calls. Under 0.5.0, an environment that resolves JSONSchema 1.6 fails to precompile EarthSciAST.
- Spec fixes (#570):
minandmaxpropagate NaN in every argument position (esm-spec §4.2, §4.9.5; CONFORMANCE_SPEC §5.23). Rust still drops NaN there, tracked in #568. searchsorted tables are "non-decreasing" (§9.2). Several CONFORMANCE_SPEC sections were renumbered: the second §5.45 is now §5.52. - A Lean model of the spec has started under
formal/(#570), with an inventory of everyMUSTclause and an audit gate. It does not affect any binding.
Breaking changes
None marked in the commit messages (type!: or BREAKING CHANGE:); see the changelog below.
Changelog
- chore(release): v0.6.0 (0aa9cf1)
- fix(ci): support JSONSchema.jl 1.6 and satisfy clippy's float precision lint (ef59aa4)
- fix(reactions): address the review of the canonical lowered tree (00b9add)
- fix(reactions): update the API examples and satisfy staticcheck (b6700ef)
- fix(reactions): one exact lowered tree for reaction systems in every binding (b719acc)
- fix(julia): hold ModelingToolkitBase at 1.42; ensemble test for SciMLBase 3 (17e7955)
- feat(julia): accept SciMLBase 3 alongside SciMLBase 2 (b5a8c9e)
- fix(conformance): gate a configured lean participant like a required binding (26fd10e)
- fix(formal): make the audit gate fail closed (eb2ba24)
- feat(formal): pin the Lake manifest, add adapter modes and per-area registry files (ab47f6e)
- docs(spec): pin NaN in min/max, fix searchsorted wording, repair CONFORMANCE numbering (4eae71f)
- feat(conformance): optional lean participant in the cross-binding runners (dcdf0db)
- feat(formal): Lean spec-model skeleton, clause inventory and audit gate (3e3359a)
Merged pull requests:
- feat(formal): Lean spec model, phase 0 — clause inventory, audit gate, spec fixes (#570) (@ctessum-claude)
- feat(julia): accept SciMLBase 3 alongside SciMLBase 2 (#571) (@ctessum-claude)
- fix(reactions): one exact lowered tree for reaction systems in every binding (#572) (@ctessum-claude)
- chore(release): v0.6.0 (#576) (@ctessum-claude)
Closed issues:
- spec wording: searchsorted 'strictly non-decreasing', and two CONFORMANCE_SPEC sections numbered 5.45 (#569)
Installation
using Pkg; Pkg.add("EarthSciAST") # Julia
npm install @earthsciml/ast # TypeScript
pip install earthsci-ast # Python
cargo add earthsci-ast # Rust
go get github.com/EarthSciML/EarthSciAST/pkg/earthsci-ast-go
Command-line tools: esm and esm-narrative
curl -sSL https://github.com/EarthSciML/EarthSciAST/releases/latest/download/update.sh | bashOr download an archive, extract it and run install.sh (install.bat on Windows):
v0.5.0
EarthSciAST v0.5.0
A breaking release for Rust only. The .esm format stays at esm 1.3.0, and every document that loaded under 0.4.0 loads unchanged. Julia, Python, TypeScript and Go only gain features. The three Rust breaks are listed below with how to upgrade.
Breaking changes
- Rust:
SimulateErrorhas a new variant,RangeRestriction { code, message }(#557). It is raised when a range-restricted or operator-restricted right-hand side is refused. AmatchoverSimulateErrorwithout a_arm needs one more arm. - Rust:
ProblemOptionshas a new public field,runtime_array_parameters(#561). Code that buildsProblemOptionswith struct-literal syntax must set it, or end the literal with..Default::default().falsekeeps the 0.4.0 behavior. - Rust: the
precisionmodule usesArcinstead ofRc(#561).precision::variable_precisions()returnsArc<VarPrecisions>, andprecision::enter_envtakes one. ReplaceRcwithArcat those call sites.
Highlights
- Range-restricted right-hand sides (Julia and Rust, native compiler, #557). Build one operator's right-hand side and evaluate it over a tile of a horizontal decomposition, with halo cells read from an extended local array, or over a run-time list of lanes (cells or columns). Tiles' owned rows, assembled, equal the whole-domain right-hand side bit for bit. Four new error codes:
range_halo_insufficient,range_global_locality,range_selection_writes_incompleteandrange_box_invalid. In Python these calls raisecompiler_unavailable. - A public, thread-safe right-hand side with forcing sets (Julia and Rust, #561).
rhs_programbuilds once. Rust'sRhsProgram,TileProgramandLaneProgramareClone + Send + Sync, and each thread evaluates with its own workspace. Forcing is passed to every call as an immutable, epoch-stampedForcingSet. Warm calls allocate nothing. Withruntime_array_parameters, gridded parameters become forcing slots, so they can change without a rebuild. - Julia tiles compile once (#565). All tiles of an operator share the whole-domain program's generated code. On the regional-inflow test document, generated code shrank 14-fold and the first call fell from 852 s to 40 s.
- Rust's native
solveruns throughRhsProgram(#561), with no extra copy per call. Results are unchanged.
Other changes
- Python 3.9 is no longer tested in CI (#563), because
ubuntu-latesthas no Python 3.9 build. The package still declaresrequires-python = ">=3.9".
Breaking changes
None marked in the commit messages (type!: or BREAKING CHANGE:); see the changelog below.
Changelog
- chore(release): v0.5.0 (b1f81ca)
- fix(julia): address the review of tile code sharing (#540) (95d2bf6)
- test(julia): pass the forcing set in the tile code-sharing and build-scaling testsets (#540) (f57648d)
- test(julia): read the full-rank fixture spelled per cell where a test pins its cross product (#540) (bcbd9d6)
- test(julia): run the regional-inflow conformance case on every Julia, default lowering (#540) (735e8be)
- perf(julia): a tile's per-box tables cover only the cells it runs (#540) (db6e2f1)
- perf(julia): share invariant prologue locals across kernels (#540) (dde54c5)
- perf(julia): lift region-split makearray operands into their own observeds (#540) (a01140f)
- perf(julia): tiles of one operator share the whole-domain program's code (#540) (a36f324)
- ci(python): drop Python 3.9 from the test matrix (22949b9)
- docs(spec): name Julia's error for evaluating a failed lane gather (4bac5b5)
- docs(spec): a slot's kind follows the parameter, not how its value arrived (7321ebb)
- fix(rust): keep caller-supplied shaped arrays as run-time slots (d73c849)
- fix(rust): name each program-mismatch error and clear a failed lane gather (308b840)
- fix(julia): build rhs workspaces from a recorded factory; review fixes (16f4efb)
- docs(spec): renumber the range-restricted conformance section to §5.50 (bba1060)
- test(julia): run the regional-inflow conformance case on Julia 1.12+ only (#540) (3e2bfd5)
- perf(rust): reference lane reads find their scalar state by lookup (#540) (ea677cb)
- refactor(rust): keep the gathered forcing set unconditionally (bcf2e42)
- feat(rust): consume the public_rhs_program conformance suite (62e3a42)
- test(julia): consume the public_rhs_program conformance suite (ed83638)
- feat(julia): public right-hand side surface per API_SPEC 5.8 (31f5a63)
- perf(julia): restamp a vector parameter without allocating (58de5e1)
- fix(ci): halo control-flow error under the package root, ruff format (#540) (e4c928b)
- feat(rust): align the program surface with the API_SPEC contract (1681426)
- feat(rust): solve a native problem through the public program's evaluation (6679619)
- fix(rust): tile data subscripts on uncut axes and seam-crossing observeds (#540) (7d45595)
- fix(rust): halo counts recurrences and wholesale observeds (#540) (f63a2dc)
- fix(rust): selection cone, workspace identity, lane padding, interpreter forcing (#540) (9ae709e)
- test(rust): public right-hand side contract (930bd6b)
- feat(julia): reentrant rhs! on per-caller workspaces with forcing sets (5246297)
- feat(julia): esm_problem runtime_array_parameters (40c4b45)
- feat(julia): forcing epochs that need not include the process-wide count (6ca1490)
- feat(rust): public Send + Sync right-hand side with forcing sets (58fdd01)
- refactor(rust): share rule bodies, const-array scope and precision table through Arc (fd9fdb0)
- docs(spec): public thread-safe right-hand side contract and conformance suite (#541) (6288463)
- fix(julia): range-restricted programs after the PR #557 review (#540) (f24e25d)
- test(julia): keep the range-restricted conformance run within CI time (#540) (08fe8f0)
- fix(ci): read nested-path re-exports in the Rust API surface (d4f09db)
- test(rust): compiler gate, Send + Sync, allocation-free tile calls (#540) (0ce746d)
- feat(rust): range-restricted programs take the contract's layout and surface (#540) (4561284)
- test(julia): run the range-restricted right-hand-side tests (#540) (7410410)
- test(julia): range-restricted right-hand sides on a periodic 2-D stencil (#540) (6b8c789)
- feat(julia): select, halo, restrict and lanes over the native compiler (#540) (6c3f56c)
- feat(rust): range-restricted right-hand sides: select, halo, tiles and lanes (#540) (d339544)
- test(conformance): count the regional-inflow slabs' zero-coefficient reads in its halo (d5c8623)
- feat(julia): build seams and program seed for range-restricted right-hand sides (#540) (abbcc16)
- docs(spec): Send + Sync on tile and lane programs is best-effort until U4 (#540) (0d95be3)
- feat(python): range-restricted entry points raise compiler_unavailable (#540) (d0a3b6b)
- feat(spec): range-restricted right-hand sides: selection, tiles and lanes (#540) (7edd553)
- test(conformance): range_restricted_rhs fixtures, manifest and README (#540) (29aee04)
Merged pull requests:
- feat: range-restricted, operator-restricted right-hand sides: tiles with halos, and lanes (#540) (#557) (@ctessum-claude)
- feat: a public, Send + Sync right-hand side with forcing sets (#541) (#561) (@ctessum-claude)
- ci(python): drop Python 3.9 from the test matrix (#563) (@ctessum-claude)
- perf(julia): tiles share the whole-domain program's code; lower region-split rule terms once (#565) (@ctessum-claude)
- chore(release): v0.5.0 (#567) (@ctessum-claude)
Closed issues:
- RFC: Range-restricted, operator-restricted right-hand sides: tiles with halos, and lanes (#540)
- RFC: A public, Send + Sync right-hand side for earthsci-ast-rs (#541)
- Julia native: three steps of a range-restricted tile build still cost O(domain) (#566)
Installation
using Pkg; Pkg.add("EarthSciAST") # Julia
npm install @earthsciml/ast # TypeScript
pip install earthsci-ast # Python
cargo add earthsci-ast # Rust
go get github.com/EarthSciML/EarthSciAST/pkg/earthsci-ast-go
Command-line tools: esm and esm-narrative
curl -sSL https://github.com/EarthSciML/EarthSciAST/releases/latest/download/update.sh | bashOr download an archive, extract it and run install.sh (install.bat on Windows):
v0.4.0
EarthSciAST v0.4.0
A breaking release. The .esm format moves to esm 1.3.0, and documents written for 1.2.0 and earlier load unchanged. The breaks are in the Rust and TypeScript flatten types, in documents that mix binary32 and binary64 across a mount, and in the last bits of reverse scans. Each one is listed below with how to upgrade.
Breaking changes
-
Rust:
FlattenedSystemhas two new public fields,equation_contributionsandequation_lifted(#555). Code that builds aFlattenedSystemwith struct-literal syntax must set both.Vec::new()for each is accepted and means no provenance recorded. Better, take the system fromflattenand modify it. -
Rust:
FlattenErrorhas a new variant,ContributionsOutOfStep(#555). It is raised when either new list is non-empty and its length differs from the number of equations. AmatchoverFlattenErrorwithout a_arm needs one more arm. -
TypeScript:
FlattenedEquation.contributionsis required (#555). Code that builds aFlattenedEquationby hand must supply it.[{ expr: rhs, origins: [] }]is the neutral value. -
Precision now crosses a mount (#532). A mounted document's
domain.element_typeused to be dropped, so a"Float32"leaf ran in its mounter's precision without any warning. Now the leaf keeps its declared precision. As a result:- Combining one of the leaf's binary32 variables with a binary64 variable of the mounting document, in an equation or a coupling, is now the
mixed_element_typeerror. - Julia and Python refuse a binary32 variable they would compute in binary64 (
float32_unsupported), instead of returning a binary64 answer. - A reaction-system leaf whose precision differs from its mounter's is refused with the new
element_type_uncarried.
To upgrade, declare the same
element_typein both documents, or convert explicitly at the coupling. - Combining one of the leaf's binary32 variables with a binary64 variable of the mounting document, in an equation or a coupling, is now the
-
Reverse scans fold from the top (#549). A
>=or>scan, or a mirroredi <= jori < jscan, now sums from the highestjdown. All bindings and both compilers now give bit-identical results. Before, Python's dense path summed pairwise. Forward scans are unchanged. Saved references for reverse scans may move in the last bits.
Highlights
solver.external(esm 1.3.0, #554): an optional reference to an external run-configuration document. Every binding parses, validates and round-trips it, and resolves where it points without opening the file.solver.time_span(esm 1.3.0, #556): the interval a document is meant to be simulated over. Each bound is either seconds or an RFC 3339 UTC timestamp.resolve_time_spanconverts a timestamp to seconds and gives the same binary64 value in all five bindings.- Per-term provenance through flatten (#555). Each flattened equation lists the terms that make up its right-hand side and which component or coupling entry wrote each one. Canonical JSON, equality and hashing are unchanged.
- Native covers more shapes (#549, #551):
makearrayregions whose value is a prefix scan, contractions over ragged ranges, overlap joins in construction-time observeds, and nested scalar reductions inside amakearrayregion (Julia). - Rust native holds far less memory on join-heavy documents (#537), back to 0.2.0's footprint, with bit-identical results.
- A generated cross-language API reference and runnable usage guides (#531).
Breaking changes
None marked in the commit messages (type!: or BREAKING CHANGE:); see the changelog below.
Changelog
- fix(conformance): register solver.time_span's codes and classify its bounds (1a58615)
- chore(release): v0.4.0 (09db4b7)
- fix: make solver.time_span agree across the five bindings (35d9d75)
- fix(conformance): classify solver.external and register its Julia diagnostic codes (d6fd5d8)
- feat: solver.time_span, the run interval a document asks for (esm 1.3.0, #550) (bf296de)
- docs(spec): Rust records the lift in equation_lifted, not by shape (5409a36)
- fix(rust): keep caller rhs edits, carry the lift flag, scale the tendency (ee27b84)
- test(julia): compare flatten-corpus origins even when equation counts diverge (fa08544)
- fix(julia): multiplicative couple targets D(to); check contributions against equations (ad13bb5)
- test(ts): count the new term_provenance corpus case (db4b5fc)
- docs(spec): rhs is authoritative over stale contributions; multiplicative couple scales D(to) (8cabdbd)
- fix(python): keep a caller-edited rhs and scale the D(to) tendency in multiplicative couple (c3f94b8)
- fix(ts): default an empty contribution list, scale the D(to) equation in a multiplicative couple (621cf52)
- fix(go): default an empty contribution list, scale the D(to) equation in a multiplicative couple (3770513)
- docs(spec): Rust also recognizes a lifted equation by its shape (fff8d4c)
- fix(rust): key the scratch's address tables on a rule-set id, not an address (315f779)
- feat(rust): record per-term provenance through flatten (0b8e0db)
- docs(spec): name how bindings tell a lifted equation, and what the corpus test may excuse (b9a24aa)
- test(julia): compare contributions in the flatten corpus and check the invariant (5d47c14)
- feat(julia): record per-term provenance through flatten (16d7cde)
- fix(julia): read float32_unsupported as a refusal in the inline-test adapter (ed887e0)
- feat(go): record per-term provenance through flatten (d090155)
- fix(julia): move the solver.external base onto EsmFile and stop gating mounted leaves (5f33ef4)
- fix(rust): record document_base on every load and percent-encode solver.external locations (a4a5bc5)
- fix(go): percent-encode solver.external locations and read drive paths as absolute (d467038)
- fix(typescript): percent-encode solver.external locations and read drive paths as absolute (645a3f1)
- fix(python): percent-encode solver.external locations and accept drive and Path bases (6b22ebb)
- test(conformance): pin percent-encoding and the mount rule for solver.external (175b0e2)
- fix(spec): percent-encode solver.external locations, read drive paths as absolute, scope the load checks to the root (1c7f7f1)
- feat(ts): record per-term provenance through flatten (b03488b)
- style(python): state the provenance comments without history (6b187d8)
- fix(python): lower a flattened system's table lookups per contribution (2608a4b)
- docs(spec): specify per-term provenance through flatten (acecb8c)
- feat(api): declare TermOrigin, Contribution and equation_contributions (ef5ee5f)
- feat(python): record per-term provenance through flatten (a50d62b)
- Update CLAUDE.md (7afc3d0)
- feat(rust): solver.external field, 1.3.0 gate, ${ refusal and location accessor (f61833d)
- fix(rust): refuse only the built model's subsystem precision (24d205f)
- fix(julia): name the binary32 refusal a recurrence now meets first (2aa059e)
- feat(julia): solver.external field, version gate, ${ refusal and location accessor (6a45b79)
- feat(ts): solver.external version gate, ${ refusal and solverExternalLocation (704b6ff)
- feat(go): solver.external field, version gate, ${ refusal and SolverExternalLocation (d4f724c)
- feat(python): parse, gate, round-trip and resolve solver.external (7184767)
- docs: declare the solver.external symbols and the esm 1.3.0 migration rows (1116b7a)
- test(conformance): solver_external resolution suite, advisory gate and invariance pair (ca8bf28)
- test(corpus): solver.external validation fixtures (74f8532)
- feat: every binding implements esm 1.3.0 (4547540)
- feat(schema): Solver.external, and the schema id moves to esm 1.3.0 (e9df7d5)
- feat(spec): solver.external names a run-configuration document, at esm 1.3.0 (53fd038)
- test(conformance): ledger Julia native's build slope on makearray_nested_sum (6a3ba8b)
- perf(rust): fold oversized tuple lists in one walk, including rank-0 ones (9d6b942)
- fix(julia): makearray region pieces and nested loops fold from 0̄, as the interpreter now does (6d31c7c)
- test(conformance): re-measure Rust makearray_nested_sum serial speed against the new hand loop (57cff69)
- test(conformance): the Rust makearray_nested_sum hand loop allocates nothing (5b5069f)
- test(rust): an all -0.0 + reduction is +0.0, interpreter and tape (7220015)
- fix(julia): makearray region pieces fold as the interpreter does and name their equation (1680db9)
- refactor(julia): one emitter for the contraction loop, seeded as the walker is (f5418a8)
- docs(spec): state the +0.0 seed for + reductions only (e228a99)
- fix(python): seed a + reduction from +0.0, so all -0.0 terms sum to +0.0 (69e230c)
- perf(julia): walk a plain equation for filtered-operand lifts once per node (dcfb3c3)
- fix(ts): bump vitest and refresh the lockfile to clear four npm advisories (1e5f258)
- fix(rust): sink a build-time broadcast only into a reader whose group takes it in (c6c4579)
- fix(julia): seed every reduction from 0̄, the gather form's included (7875eff)
- test(conformance): ledger Rust native's serial speed on makearray_nested_sum (9096c57)
- fix(julia): key a ragged loop by identity in the merge signature (1eb09b9)
- fix(julia): a reverse strided fold's slot extent spans every corner (986e928)
- refactor(rust): mark conditional and recurrence-body positions in one place (a119272)
- refactor(rust): convert a gather or scan source to its operand in one place (9cea502)
- fix(python): sort and copy an OverlapIndex built from a pair array (93c9c03)
- perf(python): fold the dense gated reduce in whole-array passes (7485c9a)
- fix(python): fold max/min reverse scans from the top (a9968d7)
- perf(julia): the whole-array nest's per-cell build tables cost integers, not keys (080c8e9)
- docs(julia): describe the makearray scan test's shapes without change-log prose (36c851e)
- test(co...
v0.3.1
EarthSciAST v0.3.1
A compatible release: no public API was removed or changed, and model results are unchanged.
Highlights
- The native compiler covers every operation the downstream EarthSciML models use, in both Julia and Rust (#512).
- Native runs threaded by default in Julia and Rust, with results bit-identical to serial runs (#501). The Rust tape uses AVX2 by default. In Julia, Polyester is now a regular dependency rather than a weak dependency with an extension.
- Native no longer falls back to slower evaluation at run time. A rule it cannot compile is refused when the problem is built, not discovered mid-solve (#506).
- Unit checking is more thorough (#508). It now follows scoped references across mount edges, checks through the array operators (
index,reshape,transpose,concat,makearray,broadcast,faq), and raises a base to a constant-expression exponent. - The
esm-narrativecommand-line tool now ships with each release, alongsideesm, for Linux, macOS and Windows (#514). - The Linux binaries run on any glibc-based distribution from the last decade, not just the newest, and now come for ARM64 as well as x86_64 (#516).
Breaking changes
None marked in the commit messages (type!: or BREAKING CHANGE:); see the changelog below.
Changelog
- fix(julia): a version bump invalidates the precompile cache (8de51e1)
- docs(release): note the Linux binary changes in the v0.3.1 notes (dda77b4)
- ci(release): link Linux binaries against glibc 2.17; add Linux ARM64 (47a2b31)
- chore(release): v0.3.1 (81990af)
- ci(release): register Julia first, publish everything else from TagBot's tag (915ee94)
- Update classification description in README (90576be)
- fix(rust): read a fault-scan condition by offset, not by iterator walk (caa92ee)
- test(rust): a filtered-out const-array gather never faults under native (361eaea)
- fix(rust): fall back to the full box when a sub-box gather does not lower (f53e474)
- fix(rust): absorb a column sum only into a group that reads its own column (7487188)
- fix(rust): latch a later rule's tape faults after an earlier rule's run-time ones (f47d8de)
- fix(rust): keep the tape's fault order parallel to its messages (f9dcae5)
- fix(julia): keep explicit subscripts in the build-definition route (695021e)
- perf(julia): one array and parameter scope through the build-definition route (0023bbf)
- fix(julia): size the broad-phase grid in floating point before converting (63fefa2)
- fix(julia): do not memoize a const read deferred under an enclosing guard (eb18c92)
- fix(julia): do not lift a gather or reduction out of a filtered or joined faq (f5a6801)
- test(conformance): ledger the native-models families' remaining speed and build gaps (8a96eb5)
- docs(julia): state the data-gather lifting rule in hoist.jl's header (71ec184)
- perf(julia): lift a data-subscript gather over the output indices it reads (ba50902)
- fix(rust): lower a sub-box gather in a value-numbering scope of its own (66aaaf1)
- test(conformance): column families' hand loops read native's layout (f664fd4)
- test(conformance): the Python named-exclusion control holds on a tier without Python (918d606)
- fix(rust): walk a join key cone's children once (da7afc8)
- perf(rust): a data gather that reads only some box axes runs on that sub-box (9a706f5)
- perf(julia): the precompile workload leaves the process counters empty (e49cd6d)
- perf(julia): a PrecompileTools workload of small native builds (4d63a67)
- style(rust): clippy and wasm32 fixes for the folded data gathers (f225bd3)
- perf(julia): fuse a box's first two axes when it spans whole rows (645d6e7)
- perf(rust): convert an in-range data subscript through i64 (one instruction) (2b4be0d)
- perf(rust): resolve a data subscript with two compares and a truncation (b00a784)
- perf(julia): a computed key column tries the compile-once evaluator before a fill (9c7e023)
- perf(rust): a Load runs its chunk in stretches with no innermost wrap (d5122f0)
- feat(julia): compile computed join key columns once; no per-position walk under native (205b76f)
- perf(rust): a data gather whose subscript its group computes is a Load micro-op (af1b0f8)
- test(conformance): Julia goldens for join_on_parameter_key_{static,dynamic} (ddde5b2)
- docs(spec): computed join key columns compare by exact numeric equality (§5.5.8) (dfc1bf3)
- fix(rust): scoped units for reaction rates, relative-path shadowing, every array operand checked (71da87a)
- style(rust): keep the join-key cone helpers above join.rs's test module (8ee2381)
- fix(rust): the build pipeline honours a model-qualified scalar parameter override (3e1dc0f)
- perf(rust): lay a promoted contraction box out with the state; fuse multi-axis data gathers (de57345)
- fix(rust): a build-time evaluation failure says 'Interpreter build failed' once (2792e1c)
- fix(julia): an unpublished observed is read from the build's own definition (7fd42a6)
- fix(julia): scoped units in reaction rates, shadowing and shared top-level map (84a12a3)
- fix(python): scoped units built once per document, relative paths shadow, every array operand walked (94cbf70)
- fix(go): an faq with no body stays unknown, matching TypeScript (100ed22)
- test(units): shared fixtures for the PR #508 review rules (95aa4ae)
- fix(go): unitless subsystem paths shadow, array operands walked, scoped units built once (f6dfc9f)
- fix(ts): scoped-reference units shadow correctly and build once per document (1754514)
- feat(julia): computed join key columns over joins, makearray cells and inline arrays (4a436f4)
- test(rust): a later-cell gather fault under native is the interpreter's fault (cd3ed6a)
- perf(rust): split a pre-reduced group only when each worker gets a whole range (62eaf58)
- test(conformance): native_model_shapes fixtures for a join keyed on a baked parameter (36cee28)
- feat(julia): a parameter feeding a join key column is baked into the gate (28b9f6d)
- perf(rust): size pre-reduction column ranges for L2 and run small boxes whole (9f9d423)
- perf(julia): the whole-array nest walks a row of its first output index as one loop (d933751)
- feat(rust): bake a scalar parameter a join key column reads (aa84433)
- docs(spec): a scalar parameter feeding a join key column is baked (§5.5.8) (04b335c)
- perf(rust): fold a leading-axes Reduce inside its consumer, column range by range (daae1a0)
- perf(julia): interchange an affine reduction along the rows of a rank-2/3 box (2b15a78)
- fix(units): Julia checker types array operators (3a6dbb5)
- fix(units): Go checker types array operators (c55e751)
- fix(units): TypeScript checker types array operators (84066bf)
- fix(units): Python checker types array operators (2d0a950)
- fix(units): Rust array rules match the spec (64de5af)
- fix(units): array operators carry a unit in the checker (0397cae)
- fix(rust): keep the build-pipeline tape route off the wasm build (2302e3a)
- perf(julia): observed reads build the row-major cell order without sorting (6efbe7b)
- test(rust): an inline array const gather is on the overlay now (13d68c1)
- perf(julia): the dependency-free overlap broad phase bins the cells (971bea8)
- style(rust): a FaultScan const-gather candidate keeps its dims in a Vec (2414b33)
- perf(julia): the whole-array nest steps its odometer and reads runs directly (83bbfa3)
- test(rust): the pipeline's per-cell shapes now build natively after at most one walked cell (1bc0da1)
- test(rust): computed-subscript gathers are lowered now, not refused (76fd414)
- refactor(rust): keep FaultWhat small (clippy large_enum_variant) (0d5fab9)
- perf(julia): hoist a nested reduction that reads a strict subset of the output indices (7ea4b7e)
- test(julia): the two consistent mount fixtures transform on load (4478294)
- perf(rust): split a leading-axes Reduce across workers by output cell (2ccfb75)
- test(conformance): native_model_shapes goldens the Julia interpreter can now mint (845bba1)
- style(rust): cargo fmt after the native/models-rust-misc merge (e8fc2ab)
- perf(rust): data-subscript gathers round without libm and loop rows tightly (c817f6f)
- fix(julia): _def_state_time_refs skips a pinned (non-symbol) output index (08fd542)
- feat(rust): tape join-gated bodies with computed subscripts and polygon rings (911549f)
- perf(rust): fold a per-cell nested reduction in the box's own layout (b633b30)
- fix(units): Julia checks units across mounts, in faq filters and through constant exponents (af2718c)
- style(rust): cargo fmt the unit-environment changes (179c04e)
- fix(units): Go checks units across mounts, in faq filters and through constant exponents (be91a5f)
- fix(units): TypeScript checks units across mounts, in faq filters and through constant exponents (692273c)
- fix(units): Python checks units across mounts, in faq filters and through constant exponents (6c76210)
- fix(units): Rust checks units across mounts, in faq filters and through constant exponents (629828e)
- fix(units): units cross mount edges, faq filters are checked, constant exponents fold (01044b8)
- test(julia): a state-dependent observed read in a subscript is materialized (f881dd1)
- feat(julia): subscripts that read a producer or a state gather at run time (8757b51)
- test(rust): keep the fallback-shape tests on a construct native still refuses (2c2f6a8)
- feat(rust): native lowers build-time observeds the overlay declines on a standalone tape (3c7a717)
- perf(rust): reduce a nested rank-0 faq once per position of the axes it reads (8739cb1)
- docs(spec): a guarded const-array read faults only where it is taken (§5.5.5) (314ceb4)
- feat(julia): run-time subscripts and guarded out-of-range reads (8d6af80)
- feat(julia): a const-c...
EarthSciAST v0.3.0
Release v0.3.0
Changes
- fix(release): the crate's Cargo.lock entry is a version site too (7a927aa)
Installation
using Pkg; Pkg.add("EarthSciAST") # Julia
npm install @earthsciml/ast # TypeScript
pip install earthsci-ast # Python
cargo add earthsci-ast # Rust
go get github.com/EarthSciML/EarthSciAST/pkg/earthsci-ast-go🚀 Release Status
| Component | Status |
|---|---|
| Cross-Platform Binaries | ⏭️ skipped |
| Conformance Tests | ⏭️ skipped |
Release Quality: 🟡 Review Required
Release v0.2.0
Release v0.2.0
Changes
- chore(release): 0.2.0 (87d7775)
- fix(julia): reattribute a compose-merged equation to its variable's system, so CHAINED operator_compose entries keep merging (#172) (7d4c7ae)
- test(julia): measure the contraction fold's allocations inside a function (4e25b49)
- fix(julia): keep the kernel body split off Julia < 1.12 (995d0c1)
- ci(rust): test the MSRV leg with every feature except esio (81633c5)
- test(julia): pin the step-0 refusal in the flatten fixture sweep (595f4e1)
- fix(go): clear the golangci-lint findings (64e533d)
- fix(python): call the io functions that exist, and format the package (fe82fd7)
- fix(editor)!: migrate to the esm 1.0.0 variable and component model (9aeee10)
- fix(typescript): typecheck the graph conformance suite, and format four files (81ff783)
- fix(rust): repair the targets
--all-featuresbuilds (260d0a6) - fix(docs): point the site nav at the sections that exist (ebfb6a7)
- fix(julia): absolute cap on SSA tier-2 run count -- a relative bound overflows XLA's JIT sections at CONUS (f736f61)
- docs(operators): label each example's Text and JSON blocks (18df3b3)
- docs(operators): drop arrayop, pair every example with its text form (a5de19c)
- docs!: rebuild the documentation as a reference, and rework the README (6abb66c)
- docs: align documentation with the shipped APIs and layout (c3c22fd)
- docs: correct stale code comments and drop non-generalizing benchmark figures (2550dd4)
- docs(libraries-spec): retract two Analysis-tier capabilities nobody implements (99d8c24)
- fix(python): guard the scalar observed path against a zero-imaginary complex (8fbc800)
- docs(tests): close corpus defect 3 and record the measured counts (63467b4)
- fix(julia): diagnose join
oncolumns against all four binder classes (cc2786d) - fix(go): diagnose join
oncolumns against all four binder classes (bfc74b5) - fix(rust): diagnose join
oncolumns against all four binder classes (3e456e3) - fix(typescript): diagnose join
oncolumns against all four binder classes (1023bec) - fix(python): diagnose join
oncolumns against all four binder classes (2b9d5f3) - docs(migration): record the default-features solve trap found downstream (cbeb625)
- docs(julia): record the ess-oop-ssa interaction and sweep results in SSA_SPIKE.md (4631d3d)
- docs: correct four stale claims found while verifying the migration guide (6d32d23)
- docs(migration): the complete before/after guide for the coordinated release (bb13ab2)
- test(julia): pin the flag explicitly in both build arms of the ssa tests (e512be1)
- test(julia): pin ess-oop-ssa — bit-identity, engagement, AD, and the traced census (26c8c96)
- feat(julia): SSA-style class-to-class references in the :oop emitter (ESS_OOP_SSA) (10547a1)
- fix(rust): keep MessageError reachable for the one out-of-repo consumer (3c95a5d)
- docs(tests): consolidate the corpus-defect record after the phase-6b merge (1e8a5b2)
- docs(corpus): close defect #2, and record the instance of #3 it was masking (d9524d4)
- chore: drop the agent scratch directory from the tree (3c7ff0f)
- refactor(rust): route the esm CLI through the library renderers (b89df5c)
- fix(julia)!: resolve from_faq at document scope (42bb6ee)
- feat(julia): add validate_text, closing the last 4-of-5 parity hole (7b6c053)
- fix(go)!: resolve from_faq at document scope (5d3fc94)
- fix(rust): repoint the doc examples and quiet private intra-doc links (c4b3e44)
- fix(rust)!: resolve from_faq at document scope (f9a6235)
- refactor(rust): demote the simulation modules and regenerate the manifest (d6f059a)
- docs: record the H-4 Python layering as a surface change (e710859)
- fix(python): name the simulate extra when SciPy is missing (7017c29)
- feat(python): layer the loader stack out of the top-level namespace (c9be6ab)
- fix(reactions): make species order declaration order in all five bindings (f6c6a25)
- fix(typescript)!: resolve from_faq at document scope (89543b0)
- fix(python)!: resolve from_faq at document scope, and converge the index-set merge (b66baa2)
- test(corpus): add a cross-model from_faq fixture for the document-scope ruling (493c1d7)
- fix(tests): repair corpus defect 1, and diagnose defect 3 as a resolver bug (fd0ebe3)
- refactor(rust): demote the lowering and analysis passes to pub(crate) (8e00e73)
- refactor(rust): demote the document-core modules to pub(crate) (e603297)
- fix(go): uppercase the LHS/RHS initialisms on UnitWarning (3e501d2)
- refactor(rust): add the tier-2 extension seam and route consumers through it (4878024)
- spec!: resolve from_faq at document scope, and make node ids document-unique (f11afea)
- docs: record every section 8 outcome and reconcile the stale Go sections (5543347)
- fix(api): let a rename alias fold into its canonical symbol (9cffef5)
- fix(julia): update diagnostic pointers address the wire form, not the vector (1e32e81)
- docs(api): correct the species-order record, which was wrong about Rust (c5ceee2)
- fix(conformance): the Python producer must reach validate through validate_text (7bb65fc)
- fix(rust): the PDE conformance adapter reads the wrong manifest key (0d9bde4)
- chore(api): regenerate the surface manifest for the Python phase-6 work (3cab8bd)
- fix(conformance): repoint the Julia runner at expression_from_json (0da05c1)
- fix(rust): derive_odes must declare the rate parameters (390b5ba)
- chore(python)!: stop installing the conformance adapters as console scripts (d0223f8)
- docs(tests): record three valid-corpus fixtures that fail reference resolution (ad1f51d)
- feat(python): code the unit findings, publish the ERROR_CODES registry (63531bd)
- chore(api): regenerate the surface manifest for the phase-6 Rust work (5e744e5)
- docs(go): correct what ValidateText's LoadOptions actually reach (c2987b5)
- feat(python)!: lower_enums is pure; lower_enums_mut is the in-place twin (52b028a)
- docs(api): correct the justification for §5.10's Go entry (76c278f)
- feat(rust): central ERROR_CODES registry; conformance adapters behind a feature (25c1884)
- docs(api): bring §5's Go columns in line with the phase-6 changes (15d774c)
- docs(ts): record why Expression and Expr are not collapsed (8c9e432)
- fix(ts): merge the model-nested index_sets on top, as Go and Rust do (afce4f8)
- docs(api): correct the item 17 signature, which was not implementable (ffa0210)
- feat(rust)!: one build_reference_graph signature; validate_text (ed33aaf)
- feat(python)!: bare edit verbs, effective_system_kind, typed-only validate (e611bbf)
- chore(api): regenerate the surface manifest for the phase-6 Julia work (7cdf248)
- feat(julia): expose to_json_graph, the canonical graph renderer (ce09cbf)
- feat(julia): to_unicode / to_latex accept containers, like to_ascii (585f630)
- fix(julia): build_reference_graph reads the 1.0.0 index_sets registry (269931f)
- feat(julia)!: pure lower_enums, and raise EnumLoweringError not ParseError (b6bf602)
- feat(julia)!: validate takes a typed document; validate_path does the I/O (7dfd321)
- feat(julia)!: unknowns/parameters, and split the system_kind family (8e7d29b)
- feat(rust)!: typed, pure entry points for lower_enums and resolve_subsystem_refs (756f18f)
- chore(api): finish the code registry and regenerate the surface manifest (de3026c)
- feat(go): add DeriveODEs and StoichiometricMatrix (phase-5 G-3, by capability) (d0f650a)
- feat(rust): canonical graph renderers, full display domain, migration targets (a154aa1)
- style(ts): satisfy eslint and prettier on the phase-6 changes (86999e4)
- feat(go): widen the display renderers to the full domain (28feee3)
- chore(api): regenerate the surface manifest for the phase-6 TypeScript work (0099f91)
- feat(ts): port build_reference_graph, closing the last 4-of-5 stable gap (933eae6)
- refactor(ts)!: drop three dead aliases from the surface (3e6dd31)
- refactor(ts)!: split validate into validate(document) and validateText(text) (b08bbf9)
- feat(ts): add effectiveSystemKind, the third question in the family (18e6270)
- refactor(ts)!: spell three stable symbols the way the rule says (c756e37)
- feat(go)!: make lower_enums pure at the canonical name, add LowerEnumsMut (0155d88)
Installation
using Pkg; Pkg.add("EarthSciAST") # Julia
npm install @earthsciml/ast # TypeScript
pip install earthsci-ast # Python
cargo add earthsci-ast # Rust
go get github.com/EarthSciML/EarthSciAST/pkg/earthsci-ast-go🚀 Release Status
| Component | Status |
|---|---|
| Cross-Platform Binaries | ❌ failure |
| Conformance Tests | 🚫 cancelled |
Release Quality: 🟡 Review Required
Release v0.1.1
Release v0.1.1
Changes
- fix(ci): stop cross-compiling macOS/Windows binaries on the Ubuntu runner (8168b2b)
- fix(ci,rust): resolve earthsciio from crates.io; make npm and the Go tag idempotent (899d4d1)
- fix(ci): publish to PyPI outside the reusable workflow (79bf215)
- feat(go): a raw §9.7 entry point that stops at the Option-B image (585e94e)
- docs(release): refresh the runbook against what actually shipped (cca7672)
- fix(ci): repair the three release jobs that failed on v0.1.1 (019d76d)
Installation
using Pkg; Pkg.add("EarthSciAST") # Julia
npm install @earthsciml/ast # TypeScript
pip install earthsci-ast # Python
cargo add earthsci-ast # Rust
go get github.com/EarthSciML/EarthSciAST/pkg/earthsci-ast-go🚀 Release Status
| Component | Status |
|---|---|
| Cross-Platform Binaries | ⏭️ skipped |
| Conformance Tests | ⏭️ skipped |
Release Quality: 🟡 Review Required
Release v0.0.3
Release v0.0.3
Changes since v0.0.2:
- fix: auto-save uncommitted implementation work (gt-pvx safety net) (c2e604e)
- fix: remove stale SolverStrategy assertion from TestModelSummary (gt-0aq) (4704c64)
- Auto-update generated documentation (3129cfd)
- fix: restore correct dependency versions corrupted by release script (gt-7ra) (eeb5234)
- fix: set rust-version to 1.85.0 for edition 2024 and run cargo fmt (gt-7ra) (5a42cfd)
- Update release coordination status for v0.0.3 (0fb084c)
- fix: resolve all 13 npm security vulnerabilities in esm-format (gt-fdw) (4f54017)
- Update release coordination status for v0.0.3 (895f430)
- fix: improve rewrite-history.sh with correct filter-repo paths and dry-run mode (gt-b7c) (83c029f)
- Update release coordination status for v0.0.3 (fcacf09)
- fix: auto-save uncommitted implementation work (gt-pvx safety net) (5729f1a)
- chore: sync schema copies to all language packages (gt-7fp) (94010ee)
- Update release coordination status for v0.0.3 (2a69ef6)
- chore: remove docs/generated/api/python.md from git tracking (gt-bu3) (79baec3)
- Auto-update generated documentation (97b2ddb)
- feat: remove SolverStrategy from all language libraries, tests, and docs (gt-08b) (acc93cd)
- refactor: remove SolverStrategy from spec, schema, and schema copies (gt-08b) (3a69321)
- Auto-update generated documentation (9a5993a)
- fix: auto-save uncommitted implementation work (gt-pvx safety net) (433aa06)
- feat: rename couple2 to couple, require manual coupler addition (gt-bf9) (62f32cd)
- fix: auto-save uncommitted implementation work (gt-pvx safety net) (3235f12)
- feat: add subsystem inclusion by reference (local path or URL) (gt-avs) (36347dc)
- Auto-update generated documentation (e9e9a02)
- fix: fix LaTeX precedence grouping and div operator display (gt-6wk) (56aa0f6)
- fix: resolve 7 more test failures with schema and validator improvements (gt-6wk) (0edcd99)
- fix: resolve 43 of 60 TypeScript test failures after rename (gt-6wk) (a5da58d)
- Update release coordination status for v0.0.3 (3f6545a)
- feat: add coupled system flattening with dot-namespaced variables (gt-dvk) (a587ca3)
- Update release coordination status for v0.0.3 (a4d012a)
- fix: auto-save uncommitted implementation work (gt-pvx safety net) (289629a)
- chore: remove container build infrastructure (gt-5ro) (b4a4e39)
- Release v0.0.2 (fa58ef0)
Changed Packages:
- EarthSciSerialization.jl
- earthsci-toolkit
- earthsci_toolkit
- esm-editor
- esm-format
- esm-format-go
Package Versions:
- Julia EarthSciSerialization.jl: v0.0.3
- TypeScript earthsci-toolkit: v0.0.3
- Python earthsci_toolkit: v0.0.3
- Rust earthsci-toolkit: v0.0.3
Installation:
Quick Install (Binaries)
curl -sSL https://github.com/EarthSciML/EarthSciSerialization/releases/latest/download/update.sh | bashPackage Managers
# Julia
using Pkg; Pkg.add("EarthSciSerialization")
# TypeScript/JavaScript
npm install earthsci-toolkit
# Python
pip install earthsci-toolkit
# Rust
cargo add earthsci-toolkit🚀 Release Status
| Component | Status |
|---|---|
| Cross-Platform Binaries | ⏭️ skipped |
| Conformance Tests | ⏭️ skipped |
Release Quality: 🟡 Review Required