V0.30 Scope - Nonperiodic Readiness and Low-Order Finite-Difference Derivative Diagnostics#
Status: COMPLETE
v0.30 is the nonperiodic-readiness and low-order finite-difference derivative-diagnostics release.
It loosens canonical ingestion to accept structured nonperiodic boundary conditions for scalar 1D fields, adds a finite-difference derivative backend limited to u_t, u_x, and u_xx, and lands cross-cutting hygiene infrastructure (ruff, mypy, coverage) under staged enforcement. It does not change the existing periodic spectral derivative path, does not promote any new PDE, does not add a symmetry-method registry, and does not unlock any external-dataset support claim.
This file documents the frozen scope. The first executed slice is the design-only sub-release v0.30a, which adds documents, configs, and audit tests without modifying any runtime code or bumping the package version.
Release conclusion (recorded by v0.30a, finalized by v0.30 proper):
nonperiodic_readiness_and_low_order_finite_difference_diagnostics_design_only
Stable Intent#
v0.30 widens the canonical-ingestion surface from “periodic x only” to “periodic and structured nonperiodic” for scalar 1D fields, and adds a corresponding low-order finite-difference derivative backend. The existing periodic spectral path stays untouched. The release ships diagnostics, not new PDE-domain support claims.
Three explicit user paths are unlocked:
structured boundary metadata:
metadata["boundary_conditions"]["x"]becomes a structured spec withtype, optional per-face values, and explicitspecifiedprovenancefinite-difference derivative diagnostics:
u_t,u_x,u_xxon Dirichlet, Neumann, andopen_unknowndataresidual preflight on manufactured nonperiodic Heat, Burgers, and advection-diffusion fields, with interior-vs-full-grid residual domain policy
Scope#
The v0.30 release scope is:
scalar 1D nonperiodic readiness for canonical
FieldBatchinputslow-order finite-difference derivative backend (implementation limited to u_t, u_x, u_xx — no higher orders on nonperiodic data in the stable
v0.30surface)design and implementation of structured
BoundaryConditionSpeccross-cutting hygiene preparation, audit-only in v0.30a and staged enforcement in v0.30 proper
release-gate consolidation proposal (consolidation lands in v0.30 proper, not v0.30a)
The v0.30 deliverables, design-frozen in v0.30a and implemented in v0.30 proper:
structured
BoundaryConditionSpecaccepting legacy string inputs and normalizing them under a backwards-compatible loadercompute_finite_difference_derivatives(field, *, max_spatial_order=2)foru_t,u_x,u_xxonlycompute_derivatives(field, *, backend="auto", max_spatial_order=...)dispatcher that records its selection explicitly inDerivativeBatch.configresidual interior-vs-full-grid policy reported on residual summaries
Heat, Burgers, and advection-diffusion residual preflight on manufactured nonperiodic scalar fields
readiness reports updated to surface boundary-condition under-specification as
needs_attentioncross-cutting hygiene:
[tool.ruff],[tool.mypy](initially strict onsrc/pdelie/contracts.py,src/pdelie/derivatives/,src/pdelie/data/,src/pdelie/residuals/only),[tool.coverage]inpyproject.toml; new audit-only CI jobs
Deferred Scope#
Explicit non-goals (the scope-freeze test will assert these phrases are present):
no PDEBench support claim
no The Well support claim
no file loaders or broad adapter framework
no KdV nonperiodic
no KS nonperiodic
no public KS runtime API
no weak nonperiodic
no public weak derivative backend
no high-order nonperiodic finite differences
no
u_xxxoru_xxxxon nonperiodic data in the stable v0.30 surfaceno finite-transform verification for nonperiodic translations
no symmetry arena
no symmetry-method registry
no root
pdelie.discover_symmetriesno external symmetry-method ports
no new root pdelie exports
no neural or callable generator APIs
no train/test policy or leakage prevention
no PyPI or TestPyPI publication; package-index publishing remains deferred to
v1.0or later
The symmetry-method registry is the v0.30.1 deliverable, not v0.30. The PySINDy PDELibrary / WeakPDELibrary task-bridge work is v0.31. External-dataset readiness cookbooks (one scalar 1D PDEBench slice, optionally one scalar 1D The Well slice) are v0.32.
Boundary Condition Schema (Designed in v0.30a)#
The structured form is documented in docs/design/BOUNDARY_CONDITION_SPEC.md. Summary:
metadata["boundary_conditions"]["x"] = {
"type": "periodic" | "dirichlet" | "neumann" | "open_unknown",
"left": BoundaryFace | None,
"right": BoundaryFace | None,
"specified": bool,
"time_dependent": bool | None,
"notes": str | None,
}
BoundaryFace carries {"value": float | None, "time_dependent": bool, "source": "user_supplied" | "default" | "inferred_unspecified"}.
Legacy 0.1-schema payloads that present boundary_conditions["x"] as a string normalize to the structured form under the v0.30 loader; the normalization is recorded in preprocess_log under operation "schema_0_1_to_0_2_boundary_normalization". FieldBatch.SCHEMA_VERSION bumps 0.1 to 0.2; from_dict accepts both versions. v0.30a does not bump the schema; v0.30 proper does.
Derivative Backend Policy (Designed in v0.30a)#
The full policy is documented in docs/design/DERIVATIVE_BACKEND_POLICY.md. Summary:
spectral_fdremains periodic-only; the check atsrc/pdelie/derivatives/spectral_fd.py:32-33is unchangedfinite_differencev1 supportsu_t,u_x,u_xxon Dirichlet, Neumann, andopen_unknowndatau_xxxandu_xxxxon nonperiodic data are not part of the stable v0.30 surfacecompute_derivatives(backend="auto")dispatch is explicit:DerivativeBatch.configrecordsbackend_selected_by_boundary_conditionandbackend_selection_reasonresidual domain policy on nonperiodic FD-derived residuals defaults to
interior_onlyfinite-transform translation verification on nonperiodic data is deferred to v0.31.5 (overlap-crop design)
Hygiene Audit (Performed in v0.30a)#
The audit baseline is documented in docs/design/V0_30_HYGIENE_AUDIT.md. Headline findings:
no
[tool.ruff],[tool.mypy], or[tool.coverage]inpyproject.tomltodayCI runs only Python 3.11
numpy>=1.24,<2is the current upper-bound cap26 per-release-gate test files exist; consolidation is proposed via a parameterized test driven by a manifest file
optional-dependency lazy import pattern at
src/pdelie/discovery/pysindy_adapter.py:12-20is the reference implementation; the audit confirms the policy must remain unchangedstrict JSON /
allow_nan=Falsediscipline confirmed; the audit confirms new outputs must follow it
Staged enforcement (no implementation in v0.30a, designed only):
Phase 0 (v0.30a): audit-only
Phase 1 (v0.30 proper): ruff, mypy (strict on core modules, lenient elsewhere), coverage; non-blocking CI
Phase 2 (v0.30.1 or v0.31): mypy strict across
src/pdelie/; blocking CIPhase 3 (v0.32): Python 3.11 / 3.12 / 3.13 matrix; numpy 2.x side-job validation
Phase 4 (v1.0): lift
numpy<2cap once 2.x validation has soaked
Milestone Status#
Milestone 0: scope freeze and design documents - COMPLETE (in v0.30a)
Milestone 1: structured
BoundaryConditionSpecruntime - COMPLETE (in v0.30b)Milestone 2:
compute_finite_difference_derivativesand dispatcher - COMPLETE (in v0.30c)Milestone 3: residual domain policy uptake in summaries - COMPLETE (in v0.30c) and residual evaluator auto-dispatch - COMPLETE (in v0.30d)
Milestone 4: manufactured nonperiodic residual preflight tests - COMPLETE (in v0.30c and v0.30d)
Milestone 5: ruff/mypy/coverage Phase 1 in
pyproject.tomland CI - COMPLETE (in v0.30e, non-blocking)Milestone 6: release-gate consolidation - COMPLETE narrowly (in v0.30f; manifest-driven, zero file deletions)
Release Gate (v0.30 close)#
v0.30.0 shipped with the following criteria satisfied:
FieldBatch.SCHEMA_VERSIONis"0.2"andfrom_dictaccepts both"0.1"and"0.2"payloads — landed inv0.30b.compute_finite_difference_derivativesis importable frompdelie.derivativesand supportsu_t,u_x,u_xxon Dirichlet/Neumann/open_unknowndata — landed inv0.30c.compute_derivatives(backend="auto")is importable and records its selection explicitly inDerivativeBatch.config— landed inv0.30c.Heat, Burgers, advection-diffusion, and reaction-diffusion residual evaluators route through
compute_derivatives(backend="auto")when derivatives are omitted — landed inv0.30d.summarize_residual_batchandsummarize_field_batch_readinessexposeresidual_domain_policyandboundary_condition_warningsrespectively — landed inv0.30c.[tool.ruff],[tool.mypy],[tool.coverage]are configured inpyproject.toml; thelint,typecheck, andcoverageCI jobs run as advisory / non-blocking — landed inv0.30e. Promotion to blocking is Phase 2 (post-v0.30).The parameterized release-gate consolidation lands as
configs/release_gate_manifest.json+tests/test_release_gates.py. Narrowly: no per-versiontests/test_v0_NN_release_gate.pyfile is deleted; the consolidation is by manifest addition. Files that use assertion patterns outside the 11 supported classes stay in-place and are listed inexcluded_functional_release_gate_files— landed inv0.30f.The v0.30 declarative gate is a row in
configs/release_gate_manifest.jsonreplayed bytests/test_release_gates.py; a standalonetests/test_v0_30_release_gate.pyfile is intentionally not added.The full test suite passes.
Package metadata is bumped to
0.30.0;numpy>=1.24,<2andrequires-python >=3.11are unchanged.Git-tag-only; PyPI/TestPyPI remain deferred to
v1.0or later.
v0.30a Sub-Release Gate#
v0.30a is complete when:
this scope document is in place and the scope-freeze test passes
the three design documents in
docs/design/are in placedocs/planning/ROADMAP.mdrecords v0.30adocs/planning/PLAN.mdrecords v0.30a as IN_PROGRESS with the decision labeldocs/specs/API_STABILITY.mdcontains a “Decision-only note for the frozen v0.30a” subsectionconfigs/planning/v0_30_nonperiodic_readiness_scope.jsonis present and strictly JSON-compatible (allow_nan=False)tests/test_v0_30_scope_freeze.pyandtests/test_v0_30_hygiene_audit.pypassthe full test suite still passes
no file under
src/pdelie/is modifiedno version bump in
pyproject.tomlno new optional dependency added
no new CI job added