PDELie - Execution Plan (V0.31.0 Release Close)#
Status: COMPLETE
V0.31.0 is complete. This is the mechanical release-close record.
Release decision: downstream_discovery_task_bridge.
Release close closes the v0.31 downstream-discovery task-bridge slice:
v0.31a — design-only scope freeze (PR #84).
v0.31b0 — PySINDy term-mapping golden + PDL-JSON debt tickets + preflight audit + label-registry fix (PR #94).
v0.31b1 — executable periodic PySINDy
PDELibrarytask runner +discovery_task_result(22-key strict-JSON schema); adapter loosening for a caller-suppliedpysindy_model(PR #95).v0.31b2 — diagnostic-only
WeakPDELibrarywrapper +pdelie_weak_pde_library_diagnostic(27-key strict-JSON schema;diagnostic_only = True) (PR #96).v0.31b3 — temporary PySINDy 1.x compatibility policy (
C_temporary_1x_policy) + compatibility-matrix JSON + CI pins (PR #97).v0.31c — public JSON-only downstream task-bridge example (submodule-only, seven-key composed wrapper — NOT a new schema); mandatory clean-install audit outcome A; xfail ledger (PR #98).
v0.31c1 — adversarial setuptools 81/82/83 install matrix (verdict
B_setuptools_82_boundary); narrow temporarysetuptools<82; python_version<'3.12'cap on[downstream]and[test]extras; RNG audit refactor to a private_legacy_numpy_rng_seed_scopecontext manager (PR #99).v0.31.0 release close (this PR) — version bump
0.30.0 → 0.31.0;docs/releases/V0_31_RELEASE_READINESS.md,docs/specs/support_matrix.v0_31.json,CHANGELOG.md; CI release-gate job renamev0_30-release-gate → v0_31-release-gate; scope status → COMPLETE; Python 3.12+ downstream UX targeted-message change.
Non-goals at release close (preserved verbatim from earlier sub-releases):
No new discovery backend. No new summary type. No change to the 22-key
discovery_task_resultschema. No change to the 27-keypdelie_weak_pde_library_diagnosticschema.No WSINDy benchmark claim. No noise-robustness claim. No nonperiodic PySINDy discovery. No PySINDy 2.x code.
No SymmetryMethod registry. No SymmetryCandidate runtime. No new root exports.
No PDEBench / The Well support claim. No multi-channel or 2D widening.
numpy>=1.24,<2unchanged.pysindy>=1.7.5,<2unchanged.setuptools<82; python_version<'3.12'retained. Python support policy unchanged.No PyPI or TestPyPI publication.
No git tag created — deferred to explicit authorization after review.
Retained xfails (final v0.31.0 ledger, 3 entries): all in tests/test_v0_31b3_pysindy_compatibility_policy.py; every entry carries a non-empty reason; all deferred to v0.31.1 (runtime version guards on the two task entry points) or to a nested provenance follow-up (scipy on _resolve_backend_version).
PDELie - Execution Plan (V0.31c1)#
Status: IN_PROGRESS
v0.31c1 is a tiny pre-release compatibility milestone that hardens pdelie[downstream] against the realistic Python 3.11 environment where the ambient setuptools has already been upgraded past pkg_resources removal. It ships:
A mandatory adversarial install matrix on fresh Python 3.11 venvs with
setuptoolsforce-pinned to81.0.0,82.0.0, and83.0.0beforepip install "<wheel>[downstream]". Verdict: B_setuptools_82_boundary. Setuptools 81 works (with a removal warning); 82 and 83 fail withModuleNotFoundError: No module named 'pkg_resources'atimport pysindy, because pysindy 1.7.5 importspkg_resourcesat package init and setuptools 82 removed the module.A narrow temporary constraint added to the
[downstream]and[test]extras:setuptools<82; python_version < '3.12'. Rebuilt-wheel post-fix verification confirms pip auto-downgrades an ambient setuptools 82/83 to 81 without any user co-install. Fresh-venv baseline unaffected (setuptools stays at the bundled65.5.0).A small RNG-audit refactor: the v0.31c example’s inline
try/finallynp.randomseed/restore is extracted into a private_legacy_numpy_rng_seed_scope(seed)context manager. Deterministic behavior preserved verbatim; the manager’s docstring documents that the workaround is not thread-safe because PySINDy 1.7.5 uses the legacy global RNG. No concurrency API is exposed.tests/test_v0_31c1_downstream_packaging_policy.py(9 named tests) asserting: the extra declares the boundary; every runtimesetuptoolscap is bounded and Python-version-scoped; the policy doc records the reason; PySINDy pin stays>=1.7.5,<2; the 22-key and 27-key public schemas are unchanged; no new root exports; the installed wheel metadata declares the cap underextra == 'downstream'; the pip resolver plan downgrades an ambient setuptools past 82.Documentation updates:
PYSINDY_COMPATIBILITY_POLICY.mdgains a “v0.31c1 adversarial install matrix — outcome B” section with the boundary table and post-fix verification;configs/pysindy_compatibility_matrix.jsongains av0_31c1_packaging_auditblock; ROADMAP marks v0.31c completed and v0.31c1 in progress.
Decision label:
adversarial_downstream_install_audit_and_setuptools_cap
Non-goals for v0.31c1:
No new summary type. No change to the 22-key
discovery_task_resultschema. No change to the 27-keypdelie_weak_pde_library_diagnosticschema.No PySINDy 2.x port. Pin stays
pysindy>=1.7.5,<2.No new root export.
No new PDE. No symmetry-method registry. No WSINDy claim. No noise benchmark. No FD-nonperiodic discovery. No additional example.
No package version bump. No tag. No PyPI/TestPyPI publication.
No stricter-than-necessary cap: the constraint is
setuptools<82, not<81— the audit proved 81 works.No release-gate manifest sub-release row for v0.31c1 (dependency policy is expressed via
pyproject.toml+ the compatibility-matrix JSON; the existing0.31manifest row is unchanged).
Files touched in v0.31c1:
MODIFIED
pyproject.toml— addsetuptools<82; python_version < '3.12'to[downstream]and[test]extras.MODIFIED
src/pdelie/examples/downstream_discovery_task_bridge.py— extract_legacy_numpy_rng_seed_scopecontext manager.NEW
tests/test_v0_31c1_downstream_packaging_policy.py— 9 named tests.MODIFIED
docs/design/PYSINDY_COMPATIBILITY_POLICY.md— adversarial-matrix section.MODIFIED
configs/pysindy_compatibility_matrix.json—v0_31c1_packaging_auditblock.MODIFIED
docs/planning/PLAN.md,docs/planning/ROADMAP.md.
PDELie - Execution Plan (V0.31c)#
Status: IN_PROGRESS
v0.31c is the final sub-release of the v0.31 arc before the mechanical release-close PR. It ships:
A mandatory clean-install audit that proves the advertised
pip install "<wheel>[downstream]"command is self-sufficient on Python 3.11 (outcome A) — no manual pre-install of setuptools/PySINDy/NumPy/SciPy/scikit-learn is required.pyproject.tomlis unchanged; the existingpython_version < '3.12'marker already handles the Python 3.12+pkg_resourcesfootgun via the ambient CIsetuptools<81co-install.One compact JSON-only public example —
pdelie.examples.run_downstream_discovery_task_bridge_exampleand CLIpython -m pdelie.examples.downstream_discovery_task_bridge— that demonstrates both v0.31 paths (run_pysindy_pde_task+inspect_pysindy_weak_pde_library) side-by-side on one canonical periodic scalar 1D Heat field. The example is deterministic under a frozen seed, records exact backend versions, and encodes its scope boundaries as machine-readable non-claim flags plus interpretation prose.An xfail audit covering every currently-declared xfail (3, all in
tests/test_v0_31b3_pysindy_compatibility_policy.py); each has a non-empty reason, each defers to v0.31.1 (PySINDy 2.x port) or to a nested provenance addition already implicit in the b3 policy.Preflight notes for the v0.31 support-matrix additions, stored in this doc rather than as a finalized
support_matrix.v0_31.json— the finalized matrix belongs in the release-close PR.
Decision label:
downstream_task_bridge_public_example_and_install_self_sufficiency
Non-goals for v0.31c:
No new scientific algorithm and no new report schema.
No PySINDy 2.x port (deferred to
v0.31.1).No change to the 22-key
discovery_task_resultschema.No change to the 27-key
pdelie_weak_pde_library_diagnosticschema.No new PDE. No symmetry-method registry. No WSINDy claim. No noise benchmark. No FD-nonperiodic discovery.
No root
pdelieexport. No package version bump. No tag. No PyPI/TestPyPI publication.No
setuptools<81constraint added to the[downstream]extra (the clean-install audit demonstrated it is not needed on Python 3.11).
Files touched in v0.31c:
NEW
src/pdelie/examples/downstream_discovery_task_bridge.pyMODIFIED
src/pdelie/examples/__init__.py(re-export the new runner)NEW
tests/test_v0_31c_downstream_task_bridge_example.py(15 named tests)MODIFIED docs:
PLAN.md,ROADMAP.md,API_STABILITY.md,PYSINDY_COMPATIBILITY_POLICY.mdMODIFIED
configs/release_gate_manifest.json(single “0.31” row extended; no new sub-release row;release_countstays 19)
Support-matrix preflight (draft only — final content lives in the release-close PR):
PySINDy
PDELibrarytask: supported for periodic scalar 1D under PySINDy 1.x (v0.31b1).WeakPDELibrarydiagnostic: diagnostic-only, no benchmark claim (v0.31b2).PySINDy 2.x: deferred to
v0.31.1.FD-nonperiodic PySINDy discovery: unsupported / deferred.
WSINDy / noise robustness: explicitly unsupported claim.
Retained xfails (release-readiness ledger draft):
test node id |
reason |
disposition |
|---|---|---|
|
runtime version guard not yet landed on |
KEEP as xfail |
|
runtime version guard not yet landed on |
KEEP as xfail |
|
asks |
KEEP as xfail — nested provenance extension deferred to a follow-up |
Every xfail carries a non-empty reason. None of the xfails represent a genuine failure being masked to make the suite green. None have been converted stale.
PDELie - Execution Plan (V0.31b3)#
Status: IN_PROGRESS
v0.31b3 is the third runtime sub-release under the v0.31 arc. It does not ship a new PDE, a new schema, a new symmetry-registry surface, a new discovery task type, or a new WSINDy claim. Its scope is entirely downstream compatibility hardening: it formalizes the existing pysindy>=1.7.5,<2 pin as a declared temporary policy, documents the exact PySINDy versions the pdelie.tasks.* runtime is verified against, records the four independent 2.x-API deltas that a future v0.31.1 / v0.32 shim will need to absorb, and reflects the policy into configs/release_gate_manifest.json, configs/pysindy_compatibility_matrix.json, and the CI matrix. pyproject.toml stays pinned at 0.30.0.
Decision label:
downstream_pysindy_compatibility_policy_and_wheel_hardening
Chosen outcome: C_temporary_1x_policy. The env-audit phase verified that pysindy 1.7.5 passes 61/61 targeted pdelie.tasks.discovery / pdelie.tasks.weak_pde_library tests against the current pdelie 0.30.0 code, while pysindy 2.1.0 HARD-breaks on three independent axes (SINDy(feature_names=, discrete_time=) constructor kwargs removed, WeakPDELibrary(library_functions=, function_names=, interaction_only=) kwargs removed, SINDy.differentiate removed) plus a transitive numpy>=2 floor conflict with pdelie’s numpy<2 pin (21/61 targeted tests fail on 2.1.0; pip rejects joint install with ResolutionImpossible). The correct v0.31b3 posture is therefore to declare the existing pysindy>=1.7.5,<2 pin as an intentional temporary policy, document the setuptools<81 install footgun for the 1.x line, and defer PySINDy 2.x support to a dedicated migration release. No compat shim is added in v0.31b3.
Sub-release contents (v0.31b3)#
docs/design/PYSINDY_COMPATIBILITY_POLICY.md(NEW) — the authoritative policy document. Enumerates the supported PySINDy range (1.7.5only under the pinned>=1.7.5,<2constraint), the primary tested version (1.7.5; no secondary), the unsupported ranges (<1.7.5and>=2.0.0) with per-axis rationale, the exact public pdelie surfaces covered (pdelie.tasks.discovery.run_pysindy_pde_task,summarize_discovery_task_result,PySINDyDiscoveryUnsupportedBoundaryError;pdelie.tasks.weak_pde_library.inspect_pysindy_weak_pde_library,summarize_pysindy_weak_pde_library_diagnostic,WeakPDELibraryDiagnostic), the nine known 1.x-vs-2.x API-diff rows recorded for the future shim, thesetuptools<81install footgun for pysindy 1.x, the CI matrix summary, and a reserved “Resource envelope” section for the follow-on resource-envelope phase to append its numbers. Also explicitly declares the non-claims: no WSINDy benchmark, no noise robustness claim, no nonperiodic discovery, no PDEBench / The Well support claim, noweak_1dretirement, no PySINDy 2.x support.configs/pysindy_compatibility_matrix.json(NEW) — strict-JSON machine-readable matrix undersummary_type = "pdelie_pysindy_compatibility_matrix",summary_schema_version = "0.1". Carriespolicy_outcome,pyproject_constraint,primary_tested_version,secondary_tested_version(null),supported_versions,unsupported_versions, andci_matrix. Loads underjson.loads(json.dumps(m, allow_nan=False)) == m.configs/release_gate_manifest.json(MODIFIED) — the existing0.31row is extended in place (no new0.31b3row;release_countstays 19).forbidden_root_attributes.namesgrows to reject the future compat-shim leak surface (_pysindy_compat,SUPPORTED_PYSINDY_VERSIONS) so those names cannot silently reach thepdelieroot when the shim is later introduced.forbidden_submodule_attributesmirrors the same forbiddance for thepdelie.discovery,pdelie.tasks,pdelie.tasks.discovery, andpdelie.tasks.weak_pde_librarysubmodules. Astrict_json_manifestsentry is added forconfigs/pysindy_compatibility_matrix.json. Every v0.31b1 and v0.31b2 assertion is preserved verbatim..github/workflows/ci.yml(MODIFIED) — narrow, additive change: the two existing blocking jobs (editable-tests,v0_30-release-gate) have their PySINDy version made explicit via anenv: PDELIE_PINNED_PYSINDY_VERSION: "1.7.5"variable and an install-timepython -m pip install "pysindy==1.7.5"step immediately after the.[test]install. The.[test]extra already resolves topysindy>=1.7.5,<2; the explicit pin makes the CI’s exercised version match the compatibility matrix’s declared primary tested version. Both jobs run the v0.31b3 test file (tests/test_v0_31b3_pysindy_compat_policy.py) alongside the existing v0.30 release-gate suite; both remain blocking. No other CI job is modified; the Python version matrix is unchanged.docs/specs/API_STABILITY.md(MODIFIED) — appends a new sub-note under the v0.31b2 stable public-surface note recording the declared temporarypysindy>=1.7.5,<2compatibility policy, the fact that any future_pysindy_compathelpers are private (no root export, no submodule public re-export), and a pointer todocs/design/PYSINDY_COMPATIBILITY_POLICY.md. No existing text is changed.docs/planning/ROADMAP.md(MODIFIED) — v0.31b2 status moves toCompleted (PR #96); v0.31b3 gets a newIn progressrow on the planned-direction table with the decision label above; a newv0.31.1row is added for “PySINDy 2.x port” per theC_temporary_1x_policyoutcome. No existing row is deleted.docs/planning/PLAN.md(this section prepended).tests/test_v0_31b3_pysindy_compat_policy.py(Author B’s remit; not written by this author) — will exercise the manifest, JSON matrix, and installed-pysindy version at runtime.
Scope-in files (v0.31b3)#
docs/design/PYSINDY_COMPATIBILITY_POLICY.mdconfigs/pysindy_compatibility_matrix.jsonconfigs/release_gate_manifest.json(extend the0.31row in place).github/workflows/ci.yml(narrow, additive per-job change; no new job)docs/specs/API_STABILITY.mddocs/planning/ROADMAP.mddocs/planning/PLAN.mdtests/test_v0_31b3_pysindy_compat_policy.py(Author B)
Scope-out files (v0.31b3)#
Any file under
src/— the runtime is unchanged. No shim is introduced;pdelie.discovery.pysindy_adapter,pdelie.discovery._pysindy_defaults,pdelie.tasks.discovery,pdelie.tasks.weak_pde_libraryare untouched.Any file under
tests/other than the new v0.31b3 policy test file authored by Author B — the b0/b1/b2 test files are unchanged.pyproject.toml— unchanged. The existingpysindy>=1.7.5,<2pin on the[downstream]and[test]extras is the policy. No version bump. No optional-dependency addition.src/pdelie/discovery/_pysindy_compat.py— not created in v0.31b3. The compat shim is deferred tov0.31.1/v0.32when the pin is widened to admit PySINDy 2.x.docs/specs/SPEC.md,docs/specs/CONTRACTS_AND_DEFAULTS.md,docs/specs/SUPPORT_MATRIX.md,docs/specs/LABEL_REGISTRY.md— no changes. This is a compatibility-policy release, not a public-API expansion.
Explicit non-goals for v0.31b3#
No new schema; no new PDE; no new symmetry registry; no new discovery task type; no WSINDy claim; no nonperiodic discovery.
No new
pdelieruntime code, no new submodule, no new public re-export.No compat shim (
src/pdelie/discovery/_pysindy_compat.pyis not created in this sub-release).No PySINDy 2.x support.
>=2.0.0remains explicitly unsupported.No
numpy>=2floor bump. Widening the numpy floor is coupled with admitting PySINDy 2.x and is deferred tov0.31.1/v0.32.No new CI job for a per-PySINDy-version matrix — the existing two blocking jobs already exercise the sole supported PySINDy version through the
.[test]extra.No promotion of the v0.30e advisory
lint/typecheck/coverageCI jobs to blocking; Phase 2 remains deferred.No version bump in
pyproject.toml(0.30.0remains pinned).No standalone
tests/test_v0_31b3_release_gate.py; the0.31release-gate lives as a single row inconfigs/release_gate_manifest.jsonreplayed bytests/test_release_gates.py(extended in place, following the v0.30f consolidation pattern).No new label family in
docs/specs/LABEL_REGISTRY.md.No
pdelie.residuals.weak_1dremoval; retention throughv0.32close is unchanged.No public root
pdelieexport for any new name.
v0.31b3 sub-release gate#
v0.31b3 is complete when:
docs/design/PYSINDY_COMPATIBILITY_POLICY.mdexists and enumerates the supported range (1.7.5only), the primary tested version (1.7.5), the unsupported ranges (<1.7.5and>=2.0.0) with per-axis rationale, the exact six public pdelie surfaces covered, the known 1.x-vs-2.x API differences, the explicit non-claims (no WSINDy benchmark, no noise robustness claim, no nonperiodic discovery), and reserves a “Resource envelope” section for later.configs/pysindy_compatibility_matrix.jsonexists, is strict-JSON compatible (json.loads(json.dumps(m, allow_nan=False)) == m), carriessummary_type = "pdelie_pysindy_compatibility_matrix",summary_schema_version = "0.1",policy_outcome = "C_temporary_1x_policy",pyproject_constraint = "pysindy>=1.7.5,<2",primary_tested_version = "1.7.5",secondary_tested_version = null,supported_versions = ["1.7.5"],unsupported_versions = ["<1.7.5", ">=2.0.0"], and a two-entryci_matrix.The
0.31row ofconfigs/release_gate_manifest.jsonis extended in place:forbidden_root_attributes.namesincludes_pysindy_compatandSUPPORTED_PYSINDY_VERSIONS;forbidden_submodule_attributes.namesincludes the same names againstpdelie.tasks,pdelie.tasks.discovery,pdelie.tasks.weak_pde_library, andpdelie.discovery; astrict_json_manifestsentry is added forconfigs/pysindy_compatibility_matrix.json.release_countstays 19; no0.31b3row is added..github/workflows/ci.ymlrecordspysindy==1.7.5explicitly on the two existing blocking jobs (editable-tests,v0_30-release-gate) and runstests/test_v0_31b3_pysindy_compat_policy.pyalongside the existing release-gate suite. No other job is modified.docs/specs/API_STABILITY.mdcarries a compatibility-policy note that names the supported range and points todocs/design/PYSINDY_COMPATIBILITY_POLICY.md.docs/planning/ROADMAP.mdshows v0.31b2 asCompleted (PR #96), v0.31b3 asIn progress, and adds av0.31.1“PySINDy 2.x port” row.pyproject.tomlstill declaresversion = "0.30.0"; no file undersrc/is added or modified; the compat shim is deferred.
PDELie - Execution Plan (V0.31b2)#
Status: IN_PROGRESS
v0.31b2 is the second runtime sub-release under the v0.31 arc. It lands the pdelie.tasks.weak_pde_library submodule with a diagnostic-only wrapper around PySINDy’s WeakPDELibrary. The wrapper produces a separate top-level strict-JSON summary type (pdelie_weak_pde_library_diagnostic, diagnostic_only=True); it does not extend the v0.31b1 discovery_task_result shape and does not promote any PDE to supported_existing_slice. Three new submodule-only names ship (WeakPDELibraryDiagnostic, summarize_pysindy_weak_pde_library_diagnostic, inspect_pysindy_weak_pde_library), all available from pdelie.tasks.weak_pde_library and re-exported from pdelie.tasks; none is added to the pdelie root. pyproject.toml stays pinned at 0.30.0.
Decision label:
downstream_discovery_task_bridge_diagnostic_weakpdelibrary
Sub-release contents (v0.31b2)#
src/pdelie/tasks/weak_pde_library.py(NEW) — submodule housingWeakPDELibraryDiagnostic(dataclass withas_dict()),summarize_pysindy_weak_pde_library_diagnostic(strict-JSON summarizer), andinspect_pysindy_weak_pde_library(PySINDy inspector). The inspector consumes a periodic scalar 1DFieldBatch, invokes PySINDy’sWeakPDELibraryunder the frozen identifier strings (method_family = "pysindy_weak_pde_library_polynomial_gauss_v1",test_function_family = "pysindy_weak_pde_library_polynomial_bump_v1",quadrature_rule = "pysindy_weak_pde_library_composite_gauss_v1"), and returns aWeakPDELibraryDiagnosticcarrying weak-feature names, matrix/target shapes, retained/skipped-row counts, column norms, rank and condition number, and finite-value status.src/pdelie/tasks/__init__.py(MODIFIED) — re-exportsWeakPDELibraryDiagnostic,summarize_pysindy_weak_pde_library_diagnostic, andinspect_pysindy_weak_pde_libraryalongside the v0.31b1 re-exports; no new rootpdelieexport.src/pdelie/reporting/summaries.py(MODIFIED) — additive supportability-policy update insummarize_weak_form_supportabilityat lines 1942-1951: a new key"supports_pysindy_weak_library_diagnostic": Trueis inserted immediately after the existing"supports_weak_derivative_backend": Falseline. The existing"supports_weak_derivative_backend": Falsevalue is not changed; its comment / docstring is re-scoped to name the pdelie-native strong-derivative-only path explicitly. No existing key is removed; no existing value is silently flipped.Runtime boundary-condition guard (unchanged from v0.31b1): the wrapper reuses
PySINDyDiscoveryUnsupportedBoundaryError(already defined inpdelie.tasks.discovery, subclass ofScopeValidationError). Nonperiodic-x inputs raise before any PySINDy call. The two-layer periodic-only fence (task-entryis_x_periodic+to_pysindy_trajectoriesbridge gate) covers the wrapper path.Strict-JSON boundary — the wrapper summarizer routes its final payload through the existing
_validate_strict_json_compatiblehelper atsrc/pdelie/reporting/summaries.py:196-202, mirroring the v0.31b1 discovery-task-result and the earlier weak-supportability strict-JSON summaries. NaN or Inf anywhere in the payload raisesSchemaValidationError.tests/test_v0_31b2_weak_pde_library_diagnostic.py(NEW) — runtime test file for the new submodule surface (import invariants, submodule-only export shape,pdelieroot non-exposure,pdelie.taskspackage re-export), the strict-JSON contract at the composed payload boundary (NaN/Inf adversarials on numeric fields), the inspector’s periodic-only BC guard (raisesPySINDyDiscoveryUnsupportedBoundaryErroron nonperiodic-x inputs), the frozen identifier strings, the frozen top-level key set, thediagnostic_only=Truemarker, and the additive supportability-policy update insummarize_weak_form_supportability. Tests scope PySINDynumpy.productDeprecationWarning cascade narrowly viapytest.warns(...)/warnings.filterwarnings("ignore", ...)inside the specific weak-library tests; no globalwarnings=errorfilter is added.configs/release_gate_manifest.json(MODIFIED) — the existing0.31row is extended in place (no new row).required_submodule_attributesgrows to include the three new names onpdelie.tasks.weak_pde_libraryand their re-exports onpdelie.tasks.forbidden_root_attributes.namesandforbidden_submodule_attributes.namesare extended with the union of the new names andweak_pde_library(as a forbidden root attribute).release_countstays at 19; the0.31row is one row covering the whole minor.Docs updated:
docs/design/DISCOVERY_TASK_RESULT_SCHEMA.md(status line moved from RUNTIME DEFERRED to RUNTIME IMPLEMENTED for the WeakPDELibrary wrapper, plus a new section documenting the separate summary type and the 27-key top-level shape);docs/specs/API_STABILITY.md(new stable public-surface note forv0.31b2);docs/planning/ROADMAP.md(v0.31b1 marked Completed with PR #95 link; v0.31b2 marked In progress);docs/planning/PLAN.md(this section).Preflight reference —
docs/planning/PYSINDY_API_PREFLIGHT_AUDIT.mdrecorded the frozen PySINDy version (1.7.5), and a subsequent b2-specific preflight (weak_pdelibrary_available: true,weak_pdelibrary_signature: (library_functions=..., derivative_order=..., spatiotemporal_grid=..., ..., is_uniform=..., periodic=...)) verified that the installed WeakPDELibrary API is fully consumable via the samepysindy.SINDyintegration path used in v0.31b1. Three preflight assumption-diffs are recorded there and are non-blocking: (a)is_uniform=/periodic=are still functional but emit aUserWarning— b2 routes the periodic hint throughdifferentiation_methodwhere possible and scopes warning filters narrowly per-test otherwise; (b) the frozenpysindy_weak_pde_library_polynomial_gauss_v1/pysindy_weak_pde_library_composite_gauss_v1strings mislabel PySINDy’s actual method (analytical piecewise-polynomial integration under a polynomial test function) but the strings are opaque provenance labels, are deliberately distinct from pdelie-nativeweak_1d, and are carried forward verbatim; (c) PySINDy’s internalnumpy.productcascade emits ~30 DeprecationWarnings per fit — scoped narrowly per-test and not filtered globally.
Scope-in files (v0.31b2)#
src/pdelie/tasks/weak_pde_library.pysrc/pdelie/tasks/__init__.pysrc/pdelie/reporting/summaries.py(additive supportability-policy key only)tests/test_v0_31b2_weak_pde_library_diagnostic.pyconfigs/release_gate_manifest.json(extend the0.31row in place)docs/design/DISCOVERY_TASK_RESULT_SCHEMA.mddocs/specs/API_STABILITY.mddocs/planning/ROADMAP.mddocs/planning/PLAN.md
Scope-out files (v0.31b2)#
src/pdelie/tasks/discovery.py— unchanged; the v0.31b1 discovery-task runner is not extended and itsTaskResult22-key top-level shape is preserved.src/pdelie/residuals/weak_1d.py— untouched; retention guaranteed throughv0.32close.src/pdelie/discovery/*— untouched; the periodic-only bridge and the v0.31b1 config-lock loosening are preserved.src/pdelie/_boundary.py— untouched; the periodic-only-x fence is unchanged.pyproject.toml— unchanged; no version bump.docs/specs/LABEL_REGISTRY.md— not touched. The v0.31b2 wrapper reuses the existingsupportability_labelvocabulary (diagnostic_onlyis already one of the frozen values on theweak_form_supportabilityfamily, v0.24). No new label family is introduced; the wrapper adds one field on the supportability-policy dict (supports_pysindy_weak_library_diagnostic), not a new label vocabulary.
Explicit non-goals for v0.31b2#
No WSINDy design matrix, no SR3 weak sparse recovery, no weak-sparse-recovery claim of any kind.
No noise-robustness claim; no clean/noisy gate.
No PDEBench support claim, no The Well support claim, no external-dataset benchmark claim.
No validated
O((dx)^p)parity harness with pdelie-nativeweak_1d. Parity is contingent onweak_1dremoval beyondv0.32close and is deliberately deferred.No promotion of any PDE to
supported_existing_slicevia the wrapper. Thediagnostic_only=Truemarker on the wrapper payload and its condensedweak_contractblock is load-bearing.No root
pdelieexport for any of the three new names.No new label family in
docs/specs/LABEL_REGISTRY.md; the wrapper reusessupportability_label/diagnostic_onlyon the existing v0.24weak_form_supportabilityfamily.No widening of the periodic-only-x guard. Nonperiodic-x is still rejected at the task entry with
PySINDyDiscoveryUnsupportedBoundaryError.No public strong extension of
supports_weak_derivative_backend. That key staysFalseand is re-scoped in comment/docstring only to name the pdelie-native strong-derivative-only path.No FD-nonperiodic PySINDy discovery. That extension is a
v0.32.5target.No multi-channel or 2D
FieldBatchdispatch (deferred tov0.34+).No new PDE row.
No new optional dependency; no CI workflow change; no promotion of the v0.30e advisory
lint/typecheck/coveragejobs to blocking.No version bump in
pyproject.toml(0.30.0remains pinned).No standalone
tests/test_v0_31b2_release_gate.py; the0.31release-gate lives as a single row inconfigs/release_gate_manifest.jsonreplayed bytests/test_release_gates.py(extended in place, following the v0.30f consolidation pattern).
v0.31b2 sub-release gate#
v0.31b2 is complete when:
pdelie.tasks.weak_pde_libraryexists and exports exactlyWeakPDELibraryDiagnostic,summarize_pysindy_weak_pde_library_diagnostic, andinspect_pysindy_weak_pde_library; the same three names are re-exported frompdelie.tasks; no other name leaks frompdelie.tasks.weak_pde_library; no rootpdelieexport is added;pdelie.residuals,pdelie.reporting, andpdelie.discoverydo not carry any of the three new names.summarize_pysindy_weak_pde_library_diagnosticreturns a strict-JSON-compatible dict matching the frozen 27-key top-level shape;summary_type == "pdelie_weak_pde_library_diagnostic";summary_schema_version == "0.1";diagnostic_only == True;method_family == "pysindy_weak_pde_library_polynomial_gauss_v1";input_layout == "scalar_1d_uniform";_validate_strict_json_compatibleis invoked at the composed payload boundary.inspect_pysindy_weak_pde_libraryraisesPySINDyDiscoveryUnsupportedBoundaryError(the existing v0.31b1 exception) on any nonperiodic-xFieldBatchbefore any PySINDy call.summarize_weak_form_supportability’s policy dict atsrc/pdelie/reporting/summaries.py:1942-1951carries the additive"supports_pysindy_weak_library_diagnostic": Truekey immediately after"supports_weak_derivative_backend": False; theFalsevalue is unchanged; no other key is added or removed.The v0.31b1
discovery_task_result22-key top-level shape is preserved; no new top-level key is added; the condensed 4-keyweak_contractblock embedded whentarget_convention == "weak_pde_library"is unchanged from v0.31a.tests/test_v0_31b2_weak_pde_library_diagnostic.pyis present and its named tests pass; the full test suite still passes; the extended0.31row inconfigs/release_gate_manifest.jsonis enforced bytests/test_release_gates.py.No file under
src/pdelie/is added or modified beyondtasks/weak_pde_library.py,tasks/__init__.py, and the additivesummarize_weak_form_supportabilitypolicy-dict update;pyproject.tomlstill declaresversion = "0.30.0"; no CI workflow is modified.
PDELie - Execution Plan (V0.31b1)#
Status: IN_PROGRESS
v0.31b1 is the first runtime sub-release for the downstream discovery task bridge frozen by v0.31a. It lands the pdelie.tasks.discovery submodule with a periodic-only PySINDy PDELibrary-backed task runner, the composed TaskResult schema wrapper, a runtime boundary-condition guard, and a narrow loosening of the fit_pysindy_discovery config-lock to accept a caller-supplied pysindy_model. The WeakPDELibrary diagnostic wrapper (target_convention="weak_pde_library") remains deferred to v0.31b2. No root pdelie export is added. pyproject.toml stays pinned at 0.30.0.
Decision label:
downstream_discovery_task_bridge_runtime_pdelibrary_only
Sub-release contents (v0.31b1)#
src/pdelie/tasks/__init__.py+src/pdelie/tasks/discovery.py— new runtime submodule. Providesrun_pysindy_pde_task,summarize_discovery_task_result, andPySINDyDiscoveryUnsupportedBoundaryError. Submodule-only; no rootpdelieexport.PySINDyDiscoveryUnsupportedBoundaryError— new exception, subclass ofScopeValidationError. Raised at thepdelie.tasks.discoveryentry when a nonperiodic-xFieldBatchis supplied, before any PySINDy call.summarize_discovery_task_result— TaskResult wrapper. Enforces the composed schema invariants frozen indocs/design/DISCOVERY_TASK_RESULT_SCHEMA.md: 22-key top-level shape,summary_type = "discovery_task_result",summary_schema_version = "0.1",pysindy_bridge_variant = "periodic_only_v1", and strict-JSON compatibility via_validate_strict_json_compatibleat the composed payload boundary.underlying_discovery_resultembedssummarize_discovery_resultverbatim.run_pysindy_pde_task— task runner. Accepts a periodic scalar 1DFieldBatchplus optional caller-suppliedpysindy_model, runs the fit through the existing bridge, and returns aTaskResult-shaped dict. Runtime BC guard is the first check; nonperiodic-x inputs raisePySINDyDiscoveryUnsupportedBoundaryErrorimmediately.fit_pysindy_discovery— config-lock loosened. The existingconfig=None-only check (src/pdelie/discovery/pysindy_adapter.py:204) is broadened so that a caller-suppliedpysindy_modelis accepted;config=Nonedefault behavior is unchanged for existing callers.tests/test_v0_31b1_discovery_task_runtime.py— 20 named runtime tests covering the submodule surface, the runner happy path, the BC guard, the TaskResult wrapper schema invariants, the strict-JSON contract at the composed boundary, the loosenedfit_pysindy_discoveryconfig-lock, and thepysindy_bridge_variant = "periodic_only_v1"invariant.configs/release_gate_manifest.json— new0.31row (following thev0.30fconsolidation pattern; no standalonetest_v0_31_release_gate.py).Docs updated:
docs/specs/API_STABILITY.md(stable public-surface note forv0.31b1),docs/planning/ROADMAP.md(Next Planned Work rows updated),docs/planning/PLAN.md(this section),docs/design/DISCOVERY_TASK_RESULT_SCHEMA.md(status line moved from RUNTIME DEFERRED to RUNTIME IMPLEMENTED fortarget_convention="pde_library";weak_pde_libraryremains DEFERRED tov0.31b2).
Explicit non-goals for v0.31b1#
No root
pdelieexport for any of the three new names.No
SymmetryCandidatecontract or wrapper — that surface isv0.30.1responsibility.No
SymmetryMethodregistry — that is alsov0.30.1.No
WeakPDELibraryruntime — the diagnostic wrapper isv0.31b2.No WSINDy implementation and no noise-robustness claim.
No FD-nonperiodic PySINDy discovery. The bridge and the task runner are periodic-only in
v0.31b1.No PDEBench support claim, no The Well support claim.
No multi-channel or 2D
FieldBatchdispatch (deferred tov0.34+).No new PDE. The task runner is agnostic across the existing v0.30 stable PDE rows, but no new PDE row is added.
No deletion of
weak_1d. It is retained throughv0.32close per thev0.31ascope freeze.No top-level
diagnostic_onlykey onTaskResult— that key is exclusive to thepdelie_weak_pde_library_diagnosticsummary type introduced inv0.31b2.No
discovery_resultkey on the composed payload — the embedded backend-native summary lives underunderlying_discovery_resultper the design.No version bump.
pyproject.tomlstays at0.30.0.
v0.31b1 sub-release gate#
v0.31b1 is complete when:
src/pdelie/tasks/__init__.pyandsrc/pdelie/tasks/discovery.pyexist and export exactlyrun_pysindy_pde_task,summarize_discovery_task_result, andPySINDyDiscoveryUnsupportedBoundaryError; no other name leaks frompdelie.tasks.discovery; no rootpdelieexport is added.PySINDyDiscoveryUnsupportedBoundaryErroris a subclass ofScopeValidationErrorand is raised at thepdelie.tasks.discoveryentry on any nonperiodic-xFieldBatchbefore any PySINDy call.summarize_discovery_task_resultreturns a strict-JSON-compatible dict matching the frozen 22-key schema;underlying_discovery_resultis verbatimsummarize_discovery_result;pysindy_bridge_variant == "periodic_only_v1"on every producedTaskResult;_validate_strict_json_compatibleis invoked at the composed payload boundary.fit_pysindy_discoveryaccepts a caller-suppliedpysindy_modelkwarg without raising the historicalconfig=None-only guard;config=Nonedefault behavior is unchanged for existing callers.tests/test_v0_31b1_discovery_task_runtime.pyis present and its 20 named tests pass; the full test suite still passes; the new0.31release-gate manifest row is enforced bytests/test_release_gates.py.No file under
src/pdelie/is added beyondtasks/__init__.py,tasks/discovery.py, and the narrowfit_pysindy_discoveryloosening;pyproject.tomlstill declaresversion = "0.30.0"; no CI workflow is modified.
PDELie - Execution Plan (V0.31b0 preparatory hygiene)#
Status: IN_PROGRESS
v0.31b0 is a preparatory hygiene sub-release for the v0.31b1 runtime (pdelie.tasks.discovery implementation). It ships no runtime code, no schema surface, and no version bump (pyproject.toml stays pinned at 0.30.0). It exists to land five preparatory artifacts that de-risk the v0.31b1 implementation phase: a term-mapping golden fixture that pins the current PySINDy feature-name → PDELie canonical-term mapping, two planning tickets that inventory and stage the strict-JSON debt migration, a PySINDy API preflight audit that is a mandatory prerequisite for v0.31b1, and a documentation-anomaly fix in LABEL_REGISTRY.md. No file under src/pdelie/ is modified. No new optional dependency is added. No CI job is added.
Decision label:
preparatory_hygiene_before_discovery_task_bridge_runtime
Sub-release contents (v0.31b0)#
tests/test_v0_31b0_pysindy_term_mapping_golden.py— golden pytest suite (8 tests) that pins the current PySINDy feature-name → PDELie canonical-term mapping. Specifically: the 17-keysummarize_discovery_resulttop-level keyset; thef"{var}__x_index_{i}"bridge feature-name convention emitted byto_pysindy_trajectories; the 6-key frozencoefficient_summaryinner shape; the{train, heldout}residuals block with 4-key inner blocks (size,l2_norm,rms,max_abs); theequation_terms: dict[str, dict[str, float]]shape keyed byfeature_names; and thereturns_coefficients=Falseinvariant. STLSQ-selected term content is deliberately NOT pinned — threshold=0.1 makes term counts fragile.pytest.importorskip("pysindy", ...)gates the whole suite so the golden is skippable in minimal environments.docs/planning/PDL_JSON_1_STRICT_JSON_INVENTORY.md— planning ticket that inventories every strict-JSON call site and every schema-emitting surface insrc/pdelie/reporting/, records which surfaces currently pass_validate_strict_json_compatibleand which do not, and enumerates the outstanding strict-JSON debt items. Design-only; no runtime change.docs/planning/PDL_JSON_2_STRICT_JSON_MIGRATION.md— planning ticket that stages the migration of the debt items catalogued inPDL_JSON_1. Defines the migration ordering, the per-surface acceptance test shape, and the release-cycle in which each item lands. Design-only; no runtime change; explicitly notv0.31b1scope.docs/planning/PYSINDY_API_PREFLIGHT_AUDIT.md— preflight audit of the exact PySINDy public surfacev0.31b1will consume. Records the pinned PySINDy version, the specific classes/methods used (WeakPDELibrary,PDELibrary,SINDy,.fit,.print,.feature_names_in_,.coefficients_), their argument shapes at the pinned version, and the known-drift-risk items (feature-name string format across PySINDy minor versions). Mandatory prerequisite for v0.31b1 — the runtime PR cannot land without this audit in place.docs/specs/LABEL_REGISTRY.md— documentation-anomaly fix. Theresidual_domain_policyrow’s Source reference cell now citessrc/pdelie/reporting/summaries.py:1320-1327(the extraction/default block) rather than the vague(residual-summary path)parenthetical. Every other row in the registry cites a specific line or line range; this row now matches that style. No runtime change; the vocabulary is unchanged.
Files modified (v0.31b0)#
docs/specs/LABEL_REGISTRY.md— line-number citation fix on theresidual_domain_policyrow (see above).docs/planning/PLAN.md— this section prepended above the existingv0.31aandv0.32aplanning notes and thev0.30release-close record.docs/planning/ROADMAP.md— newv0.31b0row added ahead of thev0.31bruntime placeholder; scope-note phrasing aligned with thepreparatory_hygiene_before_discovery_task_bridge_runtimedecision label.docs/planning/index.rst—PDL_JSON_1_STRICT_JSON_INVENTORY,PDL_JSON_2_STRICT_JSON_MIGRATION, andPYSINDY_API_PREFLIGHT_AUDITadded to the planning toctree betweenV0_31_DISCOVERY_TASK_BRIDGE_SCOPEandarchive/index.
Explicit non-goals#
No
src/pdelie/change.v0.31b0is preparatory-only; the runtime implementation lives inv0.31b1.No
pyproject.tomlversion bump (0.30.0remains pinned).No runtime code. The golden fixture is JSON; the three docs are Markdown planning artifacts; the LABEL_REGISTRY fix is a citation edit.
No new optional dependency; no new PySINDy version pin (the pin is documented in
PYSINDY_API_PREFLIGHT_AUDIT.mdbut not moved).No new CI job. No promotion of the
v0.30eadvisorylint/typecheck/coveragejobs. No new release-gate manifest row (thev0.31b0gate below is enforced by the same infrastructure that enforcesv0.31a).
v0.31b0 sub-release gate#
v0.31b0 is complete when:
tests/test_v0_31b0_pysindy_term_mapping_golden.pyis present and its 8 named tests pass on current HEAD (bridge feature-name convention, summarize keyset, library_feature_names shape, equation_terms shape, coefficient_summary keyset, residuals shape,returns_coefficients=False, and a no-regression keyset assertion).docs/planning/PDL_JSON_1_STRICT_JSON_INVENTORY.mdanddocs/planning/PDL_JSON_2_STRICT_JSON_MIGRATION.mdare in place, both referenced from the planning toctree, and both explicitly annotate that they are design-only and notv0.31b1scope.docs/planning/PYSINDY_API_PREFLIGHT_AUDIT.mdis in place, records the pinned PySINDy version, enumerates the exact public surfacev0.31b1will consume, and is referenced from thev0.31b1planning ticket as a mandatory prerequisite.docs/specs/LABEL_REGISTRY.md’sresidual_domain_policyrow citessrc/pdelie/reporting/summaries.py:1320-1327; no other row is modified; the vocabulary is unchanged.The full test suite still passes; no file under
src/pdelie/is modified;pyproject.tomlstill declaresversion = "0.30.0".
PDELie - Execution Plan (V0.31a)#
Status: IN_PROGRESS
v0.31a is the design-only scope-freeze sub-release for the downstream discovery task bridge. It adds one scope document, one design document, one strict-JSON scope manifest, and two test files. No file under src/pdelie/ is modified. No new optional dependency is added. No CI job is added. The pyproject.toml version stays pinned at 0.30.0.
Decision label:
downstream_discovery_task_bridge_design_only
Sub-release contents (v0.31a)#
docs/planning/V0_31_DISCOVERY_TASK_BRIDGE_SCOPE.md— scope freeze covering thepdelie.tasks.discoverysubmodule design, theTaskResultschema shape, theWeakPDELibrarydiagnostic wrapper policy, the supportability-policy update, and the release-gate consolidation confirmation.docs/design/DISCOVERY_TASK_RESULT_SCHEMA.md— TaskResult schema design document with per-field types, the strict-JSON NaN-safety contract (_validate_strict_json_compatibleatsrc/pdelie/reporting/summaries.py:196-202), theweak_contracttrigger predicate, and the WeakPDELibrary wrapper’s distinct identifier strings.configs/planning/v0_31_discovery_task_bridge_scope.json— strict-JSON scope manifest.release = "0.31a",status = "in_progress",parent_release = "0.31",decision_label = "downstream_discovery_task_bridge_design_only",guard_no_version_bump = "0.30.0".tests/test_v0_31_discovery_task_bridge_scope.py— scope-freeze test. Loads the JSON manifest and drives every assertion from it. Enforces required literal phrases in the scope doc, PLAN, ROADMAP, and API_STABILITY. Asserts forbidden root/submodule attributes are absent. Asserts no version bump. Asserts no premature pyproject sections or CI jobs.tests/test_discovery_task_result_schema.py— TaskResult schema tests. Imports the real_validate_strict_json_compatiblefrompdelie.reporting.summariesand proves it raisesSchemaValidationErroron:NaN in
train_residual.l2_normat the TaskResult top levelNaN embedded in
underlying_discovery_result.coefficient_summary.l2_norm(the load-bearing adversarial the peer-memo review flagged as absent)NaN inside the
weak_contractsubtreepositive infinity in
train_residual.max_abs
Files modified (v0.31a)#
docs/planning/ROADMAP.md— newv0.31arow added above the existingv0.31row. Thev0.31row’s Notes now state “Design frozen by v0.31a. Runtime lands in v0.31b+.” Every other row is preserved.docs/planning/PLAN.md— this file. Prepends the v0.31a section above the v0.32a planning note and the v0.30 release-close section; earlier sections are retained below.docs/specs/API_STABILITY.md— a Decision-only note for the frozenv0.31ascope-freeze sub-release is appended after thev0.30.0stable public-surface note and thev0.30.1planning note, mirroring the shape of the v0.30a-f notes. It records the decision labeldownstream_discovery_task_bridge_design_only, states thatv0.31a adds no new runtime public API, references the composedTaskResultschema, and enumerates the deferred surfaces (SymmetryCandidate is v0.30.1 not v0.31; noise robustness deferred; multi-channel and 2D arev0.34+; LieGG / trained-model extraction isv0.35a; no PDEBench / The Well support claim; no external dataset benchmark claim).docs/planning/index.rst—V0_31_DISCOVERY_TASK_BRIDGE_SCOPEadded to the planning toctree betweenV0_30_SCOPEandarchive/index.docs/design/index.rst—DISCOVERY_TASK_RESULT_SCHEMAadded to the design toctree.
Explicit non-goals for v0.31a#
No
src/pdelie/change. This is the load-bearing v0.31a design-only guard.No version bump (
pyproject.tomlstays at0.30.0).No new optional dependency; no new PySINDy version pin.
No new CI job; no promotion of the v0.30e advisory
lint/typecheck/coveragejobs to blocking.No root
pdelieexport.No SymmetryCandidate contract or wrapper — that surface is v0.30.1 responsibility, not v0.31.
No WSINDy implementation, no weak nonperiodic surface, no noise robustness claim, no clean/noisy gate, no external dataset benchmark claim, no PDEBench support claim, no The Well support claim, no multi-channel or 2D FieldBatch dispatch, no LieGG / trained-model extraction.
No standalone
tests/test_v0_31_release_gate.pyfile. The v0.31 release-gate is a row inconfigs/release_gate_manifest.jsonreplayed bytests/test_release_gates.py, following the v0.30f consolidation pattern.
v0.31a Sub-Release Gate#
v0.31a is complete when:
the scope doc, design doc, and scope manifest above are in place and strictly JSON-compatible
docs/planning/ROADMAP.md,docs/planning/PLAN.md, anddocs/specs/API_STABILITY.mdcarry thev0.31arecords abovetests/test_v0_31_discovery_task_bridge_scope.pyandtests/test_discovery_task_result_schema.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
PDELie - Planning Note (V0.32a design freeze — method_scores / uncertainty_report / calibration_report)#
Status: PLANNED (design freeze scheduled for v0.32a)
Records the additive extension planned for pdelie.reporting.summarize_generator_confidence. This is a planning note only — it does not schedule the runtime implementation, does not bump any version, and does not touch src/pdelie/. It exists here so the label registry (docs/specs/LABEL_REGISTRY.md), the API stability policy (docs/specs/API_STABILITY.md), and the scientific positioning doc (docs/strategy/SCIENTIFIC_POSITIONING.md) can reference a single canonical decision for what “beyond confidence_label” looks like.
Motivation#
The v0.20 confidence_label (strong, qualified, failed, insufficient_evidence) is a frozen public contract. Renaming it or extending its allowed values would break tests/test_v0_20_release_gate.py and every downstream consumer that already relies on the categorical vocabulary. However, the peer review of the v0.31 arc flagged that:
users need numeric per-component scores for calibration and cross-method comparison work, not only a categorical rollup;
future release adapters (v0.33 Ko-sparse, v0.35a LieGG) naturally emit uncertainty distributions that today have nowhere to land in PDELie’s public reporting;
BARNN-style calibration studies require reliability-diagram data that
confidence_labelcannot represent.
The additive path avoids the breaking-change trap: keep confidence_label exactly as-is (v0.20 contract), and add three optional fields alongside it that default to None so existing downstream consumers are unaffected.
Planned additive fields on summarize_generator_confidence#
Design frozen at v0.32a; runtime implementation at v0.32b+. The fields are:
method_scores: dict[str, float] | None— numeric per-component scores alongside the categoricalconfidence_label. Expected keys at first ship:span_distance,residual_l2,error_curve_max,svd_condition_number. Consumers pre-registering keys must acceptNoneuntilv0.32b.uncertainty_report: dict | None— where a method emits mean / variance / HDR intervals, this is where they land. Expected shape at first ship:{"method": Literal["point_estimate", "svd_perturbation", "bootstrap", "bayesian_hdr"], "point": float, "hdr_low": float | None, "hdr_high": float | None, "samples_n": int | None}.Nonefor point-estimate methods (current default forpolynomial_translation_svd).calibration_report: dict | None— where reliability-diagram data or ECE is available. Expected shape:{"method": Literal["ece", "reliability_diagram"], "ece": float | None, "bin_edges": list[float] | None, "bin_conf": list[float] | None, "bin_acc": list[float] | None, "n": int | None}.Nonefor uncalibrated methods (all v0.30 methods).
All three fields default to None and never replace confidence_label. Existing consumers that read confidence_label continue to work without modification. Consumers that want the numeric surfaces can opt in field-by-field.
Why v0.32a (and not v0.31)#
v0.31is the discovery task bridge; it lands a newdiscovery_task_resultschema. Bundlinggenerator_confidenceextension into v0.31 would confuse two axes (task-bridge scope vs reporting-refinement scope) in one release.v0.31.5is the nonperiodic orbit/action scope decision — a decision-only sub-release that doesn’t touch reporting.v0.32is external dataset readiness cookbooks — user-facing, dataset-side, orthogonal to reporting internals.
v0.32a is the earliest natural design-freeze slot: a small planning sub-release before v0.32b cookbooks, on a release axis where reporting extensions fit cleanly. If the release cadence changes, this planning note updates its date but not its shape.
Backwards compatibility#
Field additions to
summarize_generator_confidencerequire a scope-freeze note in the release that introduces them (v0.32adesign freeze;v0.32bruntime). No existing field is removed or renamed.The
_CONFIDENCE_LABELSfrozenset insrc/pdelie/reporting/summaries.py:38is not touched — the v0.20 vocabulary is invariant.The v0.20 release gate at
tests/test_v0_20_release_gate.pycontinues to pass without modification; the added fields do not appear in that test.Downstream tooling that reads only
confidence_labelsees no change. Downstream tooling that wantsmethod_scores/uncertainty_report/calibration_reportmust acceptNoneas the frozen default for methods that don’t emit them.
Cross-references#
docs/specs/LABEL_REGISTRY.md— “Planned additive extensions” section references this planning note. Whenv0.32afreezes, the label registry gains a note thatmethod_scores/uncertainty_report/calibration_reportare additive fields on thegenerator_confidencesummary, not new label families.docs/specs/API_STABILITY.md— Surface Matrix “deferred — additive reporting fields” row references this planning note.docs/strategy/SCIENTIFIC_POSITIONING.md— “PDELie should not become Bayesian” section from the peer review is the design constraint: PDELie does not become a calibration or UQ framework, it exposes fields where methods that natively emit those quantities can land them without breaking the categorical contract.docs/strategy/VALID_BUT_NOT_USEFUL.md— the wedge principle explains whymethod_scoresis preferable to a genericconfidenceoverload. Numeric per-component scores let downstream tooling reason about the wedge; a single overloaded scalar cannot.
Not in scope for this planning note#
No
src/pdelie/reporting/summaries.pychange.No test change; existing v0.20 release gate is preserved verbatim.
No version bump;
pyproject.tomlstays at0.30.0.No new dependency; the fields are pure numerical values from existing method internals.
No renaming of
confidence_label.No promotion of
evidence_labelfrom diagnostic to pass-fail vocabulary.No commitment on
v0.32aPR shape beyond design-only; the runtime lands inv0.32b+.
PDELie - Execution Plan (V0.30 Release Close)#
Status: COMPLETE
V0.30.0 is complete as the nonperiodic-readiness and low-order finite-difference derivative-diagnostics release.
The v0.30 arc closed on 2026-07-07. Sub-releases v0.30a (scope freeze), v0.30b (BoundaryConditionSpec runtime + FieldBatch 0.2 migration), v0.30c (finite-difference backend + boundary-aware readiness), v0.30d (residual evaluator auto-dispatch + interior-only diagnostics), v0.30e (non-blocking ruff/mypy/coverage hygiene phase 1), and v0.30f (narrow declarative release-gate consolidation) all merged before this close.
Decision label:
nonperiodic_readiness_and_low_order_finite_difference_diagnostics
Release Close Actions#
pyproject.tomlversion bumped0.29.0→0.30.0; description updated to reflect the v0.30 nonperiodic-readiness content.docs/conf.pyrelease/versionstrings bumped to0.30.0/0.30.docs/releases/V0_30_RELEASE_READINESS.mdwritten, mirroring the v0.29 structure and enumerating the new public surface, retained scope, hygiene phase 1 configuration, narrow release-gate consolidation, and deferred surfaces.docs/specs/support_matrix.v0_30.jsonwritten (strict JSON) with per-PDE support, boundary-condition-support map, derivative-backend policy, residual-domain-policy, and deferred-scope list.docs/specs/SUPPORT_MATRIX.mdupdated to referencesupport_matrix.v0_30.jsonalongside the v0.29 entry.docs/releases/PUBLISHING.mdv0.29-specific language extended to name v0.30.0 as the current Git-tag-only release.docs/releases/index.rstextended to listV0_30_RELEASE_READINESS.docs/planning/V0_30_SCOPE.mdstatus flippedIN_PROGRESS→COMPLETE; milestones 1–6 flipped from “DESIGN COMPLETE, IMPLEMENTATION DEFERRED” to the concrete sub-release that landed each.docs/planning/ROADMAP.md—v0.30andv0.30fmoved to Completed Releases;v0.30becomes the current completed release; Next Planned Work now leads withv0.31(discovery task bridge) ahead ofv0.30.1(submodule-only symmetry-method registry MVP), matching the ROADMAP table order and the earlier sequencing agreement to take the discovery task bridge before the symmetry-method registry.docs/specs/API_STABILITY.md— av0.30stable public-surface note added summarizing the new submodule-only APIs (pdelie.derivatives.compute_finite_difference_derivatives,pdelie.derivatives.compute_derivatives), theFieldBatch.SCHEMA_VERSIONbump, the reporting additions (boundary_condition_warnings,residual_domain_policy), the internal-onlypdelie._boundarymodule, and the deferred surfaces.CHANGELOG.mdprepended with a## 0.30.0entry.configs/release_gate_manifest.json— newv0.30row replacing thev0.30fself-check;current_release_gate_job_namerenamedv0_30f-release-gate→v0_30-release-gate;release_countupdated. All existing rows retained.configs/planning/v0_30_nonperiodic_readiness_scope.json—status: complete,guard_no_version_bump: "0.30.0",expected_ci_jobs: ["v0_30-release-gate", ...]..github/workflows/ci.yml— release-gate job renamedv0_30f-release-gate→v0_30-release-gate.Test guards flipped:
tests/test_current_release_gate.py,tests/test_v0_30_scope_freeze.py,tests/test_v0_30_hygiene_audit.py,tests/test_v0_30e_hygiene_config.py.
Explicit Non-Goals for v0.30 Release Close#
No new runtime feature. No
src/pdelie/change beyond what already landed in v0.30b–f.No symmetry-method registry, root API, PDEBench/The Well support claim, KdV/KS/weak nonperiodic, or nonperiodic finite-transform support.
No lift of the
numpy<2cap. No Python matrix expansion. No promotion of thelint/typecheck/coverageCI jobs from advisory to blocking.No standalone
tests/test_v0_30_release_gate.pyfile — the declarative gate lives as a row inconfigs/release_gate_manifest.jsonreplayed bytests/test_release_gates.py.No PyPI or TestPyPI publication. Git-tag-only.
PDELie - Execution Plan (V0.30f)#
Status: COMPLETE (merged as PR #79)
v0.30f lands the narrow declarative release-gate consolidation proposed in docs/design/V0_30_HYGIENE_AUDIT.md. A strict-JSON manifest at configs/release_gate_manifest.json encodes 18 release rows of declarative assertions; the parameterized tests/test_release_gates.py replays them. The CI release-gate job is renamed v0_29-release-gate → v0_30f-release-gate and its invocation extended to run the manifest test alongside every retained per-version file. No runtime behavior change. No package version bump. No new dependency. No src/pdelie/ change. Zero files deleted — consolidation is by manifest addition, not by file removal.
Decision label:
narrow_declarative_release_gate_consolidation
Files touched (v0.30f)#
configs/release_gate_manifest.json— new. Strict JSON,summary_type = "pdelie_declarative_release_gate_manifest",release_count = 18, plusexcluded_functional_release_gate_fileslisting every file whose declarative content stays in-place (with per-file reason).tests/test_release_gates.py— new. Loads the manifest, runs 4 meta-level tests (strict-JSON, release-count parity, only-supported-classes, job-name/CI-workflow alignment), and one parametrized test that dispatches to a per-class handler. Failure messages always start with[v<release>][<assertion_class>]..github/workflows/ci.yml— modified. Renames the release-gate job; extends itsrun:to invoketests/test_current_release_gate.py,tests/test_release_gates.py, and every retainedtests/test_v0_NN_release_gate.py(v0.4 through v0.29). No other job change.tests/test_current_release_gate.py— modified. Expects["v0_30f-release-gate"], requires the invocation to reference the new manifest test file, and gains a"v0_29-release-gate:" not in workflowregression guard.tests/test_v0_30_hygiene_audit.py— modified. Addstest_v0_30f_release_gate_consolidation_manifest_exists,test_v0_30f_all_release_gate_files_are_retained(26 == 26), andtest_v0_30f_hygiene_audit_records_consolidation_landed. Updates the release-gate-job regex check from["v0_29-release-gate"]to["v0_30f-release-gate"].docs/design/V0_30_HYGIENE_AUDIT.md— appended “Release-gate consolidation IMPLEMENTED narrowly in v0.30f” summary; rewrote the “Release-gate consolidation” section to describe what shipped, what is excluded, and why the “delete 26 files” outcome was scoped down.docs/planning/PLAN.md— this file. Replaces v0.30e header with v0.30f header.docs/planning/ROADMAP.md—v0.30fstatus flipped fromPlannedtoIn progress(orCompletedon merge).docs/specs/API_STABILITY.md— Decision-only note for the frozenv0.30fnarrow declarative release-gate consolidation.
Explicit non-goals for v0.30f#
No deletion of any
tests/test_v0_NN_release_gate.pyfile. All 26 stay in place.No modification of any assertion inside an existing release-gate file. The manifest replays declarative content; the source files remain unchanged.
No extension of the supported-assertion-class schema beyond the 11 classes listed above. Novel patterns (forbidden phrases in a doc, CHANGELOG/README/ROADMAP_HISTORY/SUPPORT_MATRIX phrase checks, disjunctive+forbidden per-page phrase rules,
required_json_fieldson manifests) are named as schema gaps in the manifest’sexcluded_functional_release_gate_fileslist and left in their source files. Extending the schema is separate future work.No
src/pdelie/change. No runtime API. No new root export. No new optional dependency.No version bump (
pyproject.tomlstays at0.29.0).No lift of the
numpy<2cap. No Python matrix expansion. No promotion of v0.30e’slint/typecheck/coveragejobs from advisory to blocking.
PDELie - Execution Plan (V0.30e)#
Status: COMPLETE (merged as PR #78)
v0.30e lands cross-cutting hygiene phase 1 as spec’d in docs/design/V0_30_HYGIENE_AUDIT.md: [tool.ruff], [tool.mypy] (strict scope narrowed), [tool.coverage.*] in pyproject.toml, plus three non-blocking CI jobs (lint, typecheck, coverage). No runtime behavior change. No package version bump. No new optional dependency in runtime extras (only test extras).
Decision label:
hygiene_phase_1_non_blocking_ruff_mypy_coverage
Implemented Surfaces#
pyproject.toml:[tool.ruff]withtarget-version = "py311",line-length = 120,extend-select = ["E", "W", "F", "B", "I", "UP", "RUF", "NPY"],extend-exclude = ["notebooks/*.ipynb"].[tool.ruff.lint.per-file-ignores]with targeted, documented ignores. Test files carry a broad ignore for advisory patterns (B905, RUF043, RUF012) plus per-file E501/E402 for legitimate long-fixture files. Src files carry per-file E501 ignores where breaking long lines in status-return statements hurts readability.[tool.mypy]withpython_version = "3.11",warn_unused_configs,warn_unreachable,warn_redundant_casts,show_error_codes, plus astrict = trueoverride forpdelie.contracts,pdelie._boundary,pdelie.derivatives.*. Data and residuals modules are outside strict scope for v0.30e — NumPy strict-typing pain (missing type-args on ndarray without stubs) makes them impractical at strict mode without significant clutter for no correctness benefit. Broaden in v0.30.1 or later.[tool.coverage.run]withsource = ["src/pdelie"],branch = true,omit = ["*/tests/*", "*/__init__.py"].[tool.coverage.report]withshow_missing = true,fail_under = 80, standardexclude_lines.[project.optional-dependencies].testgainsruff>=0.6,mypy>=1.11,pytest-cov>=5.0.
.github/workflows/ci.yml: three new jobs onubuntu-latest/ Python 3.11, allcontinue-on-error: true:lint—python -m ruff check .typecheck—python -m mypy src/pdeliecoverage—python -m pytest --cov=src/pdelie --cov-report=xml --cov-report=term-missing, plus artifact upload ofcoverage.xml.
Src fixes applied to make the strict-scope mypy clean and the ruff rule set green:
Docstring reordered above
from __future__ import annotationsin 5 src files (symmetry/{closure,symbolic,span}.py,symmetry/_polynomial_metric.py,discovery/pysindy_bridge.py) — required to satisfy E402 without weakening the module docstring convention.5
zip(...)calls in src gainedstrict=False(behavior-preserving; documents the fixture-pairing invariant).1 unused loop variable renamed to
_indexindiscovery/pysindy_adapter.py.contracts.py: everynp.ndarrayannotation updated tonp.ndarray[Any, Any](mypy strict scope requirement). One# type: ignore[unreachable]added toGeneratorFamily.__post_init__’sif self.diagnostics is None: ...branch, which mypy narrows away based on the declared dataclass type but which is runtime-reachable because the field default isNone.derivatives/spectral_fd.pyandderivatives/finite_difference.py:typing.Anyimport +np.ndarray[Any, Any]on the one internal helper each.2 unused local variables removed (
valuesintest_finite_difference_backend.pyandplanintest_api_stability_audit.py).
Observed Metrics at v0.30e HEAD#
ruff: 442 baseline errors → 0 (192 auto-fixed via
ruff check --fix; 8 manual fixes to src; per-file-ignores added for a documented list of files, each with a rule + reason).mypy strict scope (
pdelie.contracts,pdelie._boundary,pdelie.derivatives.*): 0 errors, 5 source files checked.mypy full-tree (advisory, non-blocking): 311 errors across 44 files, dominated by
[type-arg]onnp.ndarrayindata/*andresiduals/*. These would each need[Any, Any]annotations or numpy stubs to clear. Not blocking, not shipping — captured here as a v0.30.1 or later stretch.coverage on
src/pdelie/: 86% (line + branch), well above the 80% floor.pytest: 1028 passed, 2 skipped (unchanged from v0.30d).
Tests Added#
tests/test_v0_30e_hygiene_config.py— asserts the ruff/mypy/coverage sections exist with the expected shape, test extras include the three new tools, numpy/Python/version guards are unchanged, and the three new CI jobs exist AND are non-blocking. Also guards that v0.30f’s release-gate consolidation has not preempted.
Tests Updated#
tests/test_v0_30_hygiene_audit.py:test_v0_30_no_premature_pyproject_changesinverted totest_v0_30e_pyproject_now_configures_ruff_mypy_coverage(checks presence, still guards numpy cap + Python floor + version).test_v0_30_no_premature_ci_changesinverted totest_v0_30e_ci_workflow_now_has_lint_typecheck_coverage_jobs_nonblocking(checks presence + non-blocking property + no v0.30f preemption).The 26-release-gate-file count assertion, strict-JSON, and lazy-optional-import documentation checks all stay unchanged.
Public-Surface Audit#
Confirmed in v0.30e:
no new
pdelieroot exportno new submodule runtime API
no new runtime optional dependency (only test extras: ruff, mypy, pytest-cov)
no new PDE, no KdV/KS nonperiodic, no weak nonperiodic
no PDEBench / The Well support claim
no symmetry-method registry
no
pyproject.tomlversion bump — still0.29.0no CI job becomes blocking (all three new jobs are
continue-on-error: true)no numpy cap change (still
<2)no Python matrix expansion (still 3.11-only)
v0.30e Sub-Release Gate#
v0.30e is complete when:
[tool.ruff],[tool.mypy],[tool.coverage.*]are configured inpyproject.tomlwith the exact shape spec’d inV0_30_HYGIENE_AUDIT.md.The three CI jobs (
lint,typecheck,coverage) exist and are non-blocking.Strict-scope mypy passes cleanly (0 errors).
ruff check .passes cleanly (0 errors under the configured rule set + per-file-ignores).Coverage clears the 80% floor.
The full test suite still passes.
git diff --checkreports no whitespace damage.
PDELie - Execution Plan (V0.30d)#
Status: COMPLETE
v0.30d routes the Heat, Burgers, advection-diffusion, and reaction-diffusion residual evaluators through compute_derivatives(backend="auto") and consumes the interior-only residual-domain policy that v0.30c’s finite-difference backend recommends. KdV and the weak evaluators remain periodic-only per v0.30 scope. No new optional dependency, no CI change, no version bump. Hygiene phase 1 (ruff/mypy/coverage) is deferred to v0.30e.
Release Theme#
v0.30d closes the “nonperiodic residuals” loop for the four supported strong-form evaluators. Once complete, a user can pass a Dirichlet, Neumann, or open_unknown FieldBatch to any of {Heat, Burgers, advection-diffusion, reaction-diffusion} and receive a residual whose diagnostics honor the interior-only trim policy.
Decision label:
strong_residual_evaluator_auto_dispatch_and_interior_only_diagnostics
Implemented Surfaces#
src/pdelie/residuals/base.py: shared helperbuild_residual_diagnostics_from_derivativesthat readsrecommended_residual_domain_policyandrecommended_boundary_trim_widthfromDerivativeBatch.config, computes interior-only max/RMS residuals when the recommended policy is"interior_only", and nests afull_grid_diagnosticblock for transparency.src/pdelie/residuals/heat_1d.py: derivatives default now dispatch throughcompute_derivatives(backend="auto"); diagnostics use the shared helper (addsresidual_domain_policyandrms_residualto Heat outputs).src/pdelie/residuals/burgers_1d.py: same routing and shared-helper adoption.src/pdelie/residuals/advection_diffusion_1d.py: same routing + shared helper; the directis_x_periodicearly-guard is dropped sincecompute_derivatives(backend="auto")decides the backend.src/pdelie/residuals/reaction_diffusion_1d.py: same as advection-diffusion.
Explicitly Untouched#
src/pdelie/residuals/kdv_1d.py: KdV remains periodic-only (equation == "kdv_normalized"tag + periodic-x check).src/pdelie/residuals/weak_1d.py: weak Heat/Burgers residuals stay periodic-only.src/pdelie/verification/finite_transform.py: translation finite-transform verification stays periodic-only. Nonperiodic overlap-crop design is a v0.31.5 topic.
Tests Added#
tests/test_manufactured_nonperiodic_residuals.py: manufactured-analytic solutions on Dirichlet (Heat, Burgers) andopen_unknown(advection-diffusion) plus a Fisher-KPP smoke on Dirichlet; O(h²) interior convergence for Heat; regression that periodic Heat/Burgers still route to spectral_fd withfull_gridpolicy; regression that Heat/Burgers diagnostics gainrms_residual.
Tests Updated#
tests/test_advection_diffusion_residual.py,tests/test_reaction_diffusion_residual.py: the “dirichlet-tagged data raises” parametrization is dropped — that case is now a legitimate nonperiodic residual path.tests/test_boundary_condition_internal_usage.py:test_heat_residual_evaluator_still_rejects_nonperiodic_derivative_pathreplaced bytest_heat_residual_evaluator_now_handles_nonperiodic_via_fd_dispatch.must_import_helperdropsadvection_diffusion_1d.pyandreaction_diffusion_1d.py.
tests/test_boundary_readiness_reporting.py: the “not_configured” residual-domain-policy check now uses a directly constructedResidualBatch; adds a positive test that periodic Heat emits"full_grid".tests/test_reporting.py: the frozen residual-summary policy field now expects"full_grid"for periodic Heat.
Public-Surface Audit#
Confirmed in v0.30d:
no new
pdelieroot exportno new submodule runtime API
no new optional dependency
no new PDE
no KdV nonperiodic, no KS nonperiodic, no weak nonperiodic
no PDEBench / The Well support claim
no symmetry-method registry
no
pyproject.tomlversion bump (still0.29.0)no CI workflow change
ruff / mypy / coverage configuration remains deferred to v0.30e
v0.30d Sub-Release Gate#
v0.30d is complete when:
Heat, Burgers, advection-diffusion, reaction-diffusion evaluators route through
compute_derivatives(backend="auto")when derivatives are omittedtheir diagnostics include
residual_domain_policy(and, when interior-only,boundary_trim_width+full_grid_diagnostic)KdV, weak, and translation verification remain periodic-only
manufactured-analytic tests pass with the expected tolerances
the full suite still passes
git diff --checkreports no whitespace damage
PDELie - Execution Plan (V0.30c)#
Status: COMPLETE
v0.30c lands the second runtime step of the v0.30 sequence: the low-order finite-difference derivative backend, the compute_derivatives(backend="auto") dispatcher, boundary-aware readiness warnings, and the residual_domain_policy field on residual summaries. Residual evaluator auto-dispatch is deferred to v0.30d.
Release Theme#
v0.30c implements the v1 finite_difference derivative backend (u_t, u_x, u_xx only on nonperiodic 1D scalar uniform grids) and the explicit-and-auditable compute_derivatives dispatcher. spectral_fd is unchanged. The reporting layer now surfaces boundary-condition warnings and an additive residual_domain_policy field. No new optional dependency, no version bump, no root export, no CI workflow change.
Decision label:
low_order_finite_difference_backend_and_boundary_aware_readiness
Implemented Surfaces#
src/pdelie/derivatives/finite_difference.py(NEW) —compute_finite_difference_derivatives(field, *, max_spatial_order=2)foru_t,u_x,u_xxonly on Dirichlet, Neumann, oropen_unknowndata. Usesnp.gradient(edge_order=2)for both axes.src/pdelie/derivatives/__init__.py(UPDATED) — exportscompute_finite_difference_derivativesand a newcompute_derivatives(field, *, backend="auto", max_spatial_order=2)dispatcher.backend="auto"picksspectral_fdfor periodic data andfinite_differencefor any supported nonperiodic boundary type; the selection is recorded inDerivativeBatch.configasbackend_selected_by_boundary_condition=Trueplus a non-nullbackend_selection_reason. Explicitbackend="spectral_fd"on nonperiodic data and explicitbackend="finite_difference"on periodic data both raiseScopeValidationError. The dispatcher never silently falls back from one backend to the other.src/pdelie/contracts.py(UPDATED) —ALLOWED_DERIVATIVE_BACKENDSnow includes"finite_difference"(the legacy"finite"entry is retained).src/pdelie/reporting/summaries.py(UPDATED) — two remaining direct periodic compares migrated toget_x_boundary_type.summarize_field_batch_readinessnow emitsboundary_condition_warnings: list[str]and downgrades a would-be"ready"label to"needs_attention"when warnings are present.summarize_xarray_dataset_readinessdoes the same.summarize_residual_batchnow records aresidual_domain_policyfield, sourced fromresidual.diagnostics["residual_domain_policy"]if present, else"not_configured".
Documents Added or Updated#
docs/design/DERIVATIVE_BACKEND_POLICY.md(updated status —finite_differencev1 implemented)docs/planning/PLAN.md(this file; v0.30b record retained below)docs/specs/API_STABILITY.md(new “Decision-only note for the frozenv0.30c” subsection appended after the v0.30b note)docs/planning/ROADMAP.md(v0.30c row updated; v0.30b row flipped to Completed)configs/planning/v0_30_nonperiodic_readiness_scope.json(removedpdelie.derivatives.compute_finite_difference_derivativesandpdelie.derivatives.compute_derivativesfromforbidden_submodule_attributes— they ship in v0.30c)
Tests Added#
tests/test_finite_difference_backend.py— manufactured-polynomial accuracy, max_spatial_order limits, JSON-strict config, periodic-input rejection, nonuniform-grid rejection, too-few-points rejection, structured/legacy nonperiodic BC acceptance.tests/test_derivative_dispatcher.py—backend="auto"periodic + nonperiodic routing, explicit-backend success/mismatch behavior, unknown backend rejection, no-fallback semantics,backend_selected_by_boundary_conditiononly true under auto.tests/test_boundary_readiness_reporting.py—boundary_condition_warningsfor legacy/structured periodic/nonperiodic/open_unknown, readiness label downgrade, residual-domain-policy passthrough, strict JSON compatibility, unsupported BC string routes to failure.
Tests Updated#
tests/test_reporting.py:_FIELD_BATCH_READINESS_SUMMARY_KEYSand_XARRAY_DATASET_READINESS_SUMMARY_KEYSnow includeboundary_condition_warnings.the residual-batch frozen-keys assertion now includes
residual_domain_policyand pins its default to"not_configured".the nonperiodic-field readiness case now expects
"needs_attention"plus thex_boundary_dirichlet_unspecifiedandx_boundary_legacy_string_under_schema_0_2warnings (the v0.30c behavior change).
tests/test_boundary_condition_internal_usage.py:dropped the
reporting/summaries.pyallowlist entry (no longer needed; the file now goes through the helper).must_import_helperenlarged to also list the new derivative-backend module, the dispatcher module, andreporting/summaries.py.
configs/planning/v0_30_nonperiodic_readiness_scope.json:pdelie.derivatives.compute_finite_difference_derivativesandpdelie.derivatives.compute_derivativesremoved fromforbidden_submodule_attributes.
Public-Surface Audit#
Confirmed in v0.30c:
no new
pdelieroot exportpdelie.derivatives.compute_finite_difference_derivativesandpdelie.derivatives.compute_derivativesare submodule-onlyno new optional dependency
no new PDE
no PDEBench / The Well support claim
no KdV nonperiodic
no KS nonperiodic
no weak nonperiodic
no symmetry-method registry yet
no residual evaluator auto-dispatch (deferred to v0.30d)
no
u_xxx/u_xxxxon nonperiodic data (max_spatial_order ∈ {1, 2}only)no version bump (
pyproject.tomlremains at0.29.0)no CI workflow change
v0.30c Sub-Release Gate#
v0.30c is complete when:
pdelie.derivatives.compute_finite_difference_derivativesis importable and produces correctu_t,u_x,u_xxon manufactured polynomialspdelie.derivatives.compute_derivatives(backend="auto")routes by BC and records the selection inDerivativeBatch.configsummarize_field_batch_readinessexposesboundary_condition_warningsand downgrades the label when warnings existsummarize_residual_batchexposesresidual_domain_policyall v0.30c new tests pass plus the existing v0.30a/b tests
the full test suite passes
git diff --checkreports no whitespace damage
PDELie - Execution Plan (V0.30b)#
Status: COMPLETE
v0.30b lands the first runtime step of the v0.30 sequence: the structured BoundaryConditionSpec, the FieldBatch 0.1 → 0.2 schema migration with backwards-compatible loader, and internal helpers that centralize the x-boundary-type check. Adapter ingestion is loosened to accept supported nonperiodic specs; downstream derivative and residual consumers remain strict-periodic.
Release Theme#
v0.30b implements the contracts frozen in v0.30a for boundary metadata. It modifies src/pdelie/ but adds no new optional dependency, no version bump, no root export, no CI workflow change.
Decision label:
boundary_condition_spec_runtime_and_field_batch_0_2_migration
Implemented Surfaces#
src/pdelie/_boundary.py(NEW) — internal helpersBoundaryFace,BoundaryConditionSpec,normalize_x_boundary_condition,get_x_boundary_type,is_x_periodic; module is intentionally underscore-prefixed (no submodule re-export).FieldBatch.SCHEMA_VERSIONbumped from"0.1"to"0.2".FieldBatch.LEGACY_SCHEMA_VERSIONS = frozenset({"0.1"});from_dictaccepts both versions.FieldBatch.from_dictnormalizes legacyboundary_conditions["x"]strings vianormalize_x_boundary_conditionand records aschema_0_1_to_0_2_boundary_normalizationentry inpreprocess_logfor migrated payloads.14 downstream consumer sites refactored to use
is_x_periodic(field)(preserves reject-nonperiodic semantics; no behavior change for periodic data).from_numpyandfrom_xarrayaccept structured nonperiodic specs and supported legacy nonperiodic strings; unsupported strings still raiseScopeValidationError.
Documents Added or Updated#
docs/design/BOUNDARY_CONDITION_SPEC.md(updated status — design frozen + runtime implemented)docs/planning/PLAN.md(this file; v0.30a record retained below)docs/specs/API_STABILITY.md(new “Decision-only note for the frozenv0.30b” subsection appended after the v0.30a note)docs/planning/ROADMAP.md(new v0.30b row)
Tests Added#
tests/test_boundary_condition_spec.py— direct tests for the helper module.tests/test_field_batch_schema_0_2_migration.py—FieldBatchschema 0.1 → 0.2 migration tests.tests/test_boundary_condition_internal_usage.py— invariants: downstream consumers still reject nonperiodic, adapters accept structured nonperiodic, no new direct periodic compares outside the helper module, all migrated modules import the helper.
Tests Updated#
tests/test_v0_30_scope_freeze.py:removed
test_v0_30_no_src_changes_against_main(v0.30b modifies src by design).replaced
test_v0_30_schema_migration_is_documented_but_not_yet_appliedwith two tests:test_v0_30_schema_migration_design_is_documented(still passes against the design docs) andtest_v0_30b_schema_migration_is_applied_at_runtime(assertsFieldBatch.SCHEMA_VERSION == "0.2").
tests/test_data_numpy_adapter.pyandtests/test_data_xarray_adapter.py:replaced the rejection-of-
dirichlettests with acceptance tests fordirichlet/neumann/open_unknown(the new loosened adapter behavior).added new rejection tests for unsupported BC strings (
"insulating").
Public-Surface Audit#
Confirmed in v0.30b:
no new
pdelieroot exportno new submodule runtime API
no new optional dependency
no new PDE
no PDEBench or The Well support claim
no KdV nonperiodic
no KS nonperiodic
no weak nonperiodic
no
compute_finite_difference_derivativesmodule yet (deferred to v0.30c)no
compute_derivativesdispatcher yet (deferred to v0.30c)no symmetry-method registry yet
no root
pdelie.discover_symmetriesno version bump (
pyproject.tomlremains at0.29.0)no CI workflow change
v0.30b Sub-Release Gate#
v0.30b is complete when:
FieldBatch.SCHEMA_VERSION == "0.2"FieldBatch.from_dictaccepts both"0.1"and"0.2"payloadslegacy
boundary_conditions["x"]strings are normalized vianormalize_x_boundary_conditionall 14 downstream consumer sites use
is_x_periodic(no new direct compares)from_numpy/from_xarrayaccept structured nonperiodic specs; downstream consumers still rejectthe three new tests pass plus the updated v0.30 scope-freeze tests
the full test suite passes
git diff --checkreports no whitespace damage
PDELie - Execution Plan (V0.30a)#
Status: COMPLETE
v0.30a is the scope-freeze, compatibility-audit, and design-contract sub-release that precedes v0.30.
Release Theme#
v0.30a freezes the design of nonperiodic-readiness ingestion, the low-order finite-difference derivative backend, the dispatch and residual-domain policies, and the cross-cutting hygiene audit. It adds no runtime API, bumps no package version, and modifies no file under src/pdelie/.
Decision label:
nonperiodic_readiness_and_low_order_finite_difference_diagnostics_design_only
Implemented Surfaces#
None at runtime. The sub-release is design-only.
Documents Added#
docs/planning/V0_30_SCOPE.mddocs/design/BOUNDARY_CONDITION_SPEC.mddocs/design/DERIVATIVE_BACKEND_POLICY.mddocs/design/V0_30_HYGIENE_AUDIT.mdconfigs/planning/v0_30_nonperiodic_readiness_scope.jsontests/test_v0_30_scope_freeze.pytests/test_v0_30_hygiene_audit.py
Documents Updated#
docs/planning/ROADMAP.md(newv0.30arow in Next Planned Work; refinedv0.30theme; appended deferred surfaces)docs/planning/PLAN.md(this file; v0.29 record retained below)docs/specs/API_STABILITY.md(new “Decision-only note for the frozenv0.30a” subsection appended after the v0.29 note)
Public-Surface Audit#
Confirmed in v0.30a:
no new
pdelieroot exportno new submodule runtime API
no new optional dependency
no new PDE
no PDEBench or The Well support claim
no KdV nonperiodic
no KS nonperiodic
no weak nonperiodic
no
compute_finite_difference_derivativesmodule yetno symmetry-method registry yet
no root
pdelie.discover_symmetriesno version bump (
pyproject.tomlremains at0.29.0)no CI workflow change
v0.30a Sub-Release Gate#
v0.30a is complete when:
the four design documents in
docs/design/anddocs/planning/V0_30_SCOPE.mdare in placetests/test_v0_30_scope_freeze.pyandtests/test_v0_30_hygiene_audit.pypassthe full test suite still passes
git diff --checkreports no whitespace damageno file under
src/pdelie/is modified
PDELie - Execution Plan (V0.29)#
Status: COMPLETE
V0.29 is complete as the workflow recipes and support matrix release
This file is the completed execution record for the v0.29 release series.
Release Theme#
v0.29 consolidates the existing v0.19-v0.28 surface into explicit user workflows and a machine-readable support matrix. It adds no numerical scope, no runtime helper, no new public API, and no root export.
Decision label:
workflow_recipes_and_support_matrix_complete_no_new_numerical_scope
Implemented Surfaces#
docs/workflows/with recipe pages for data readiness, candidate validation, downstream/export provenance, Dataset-to-downstream, and candidate-to-split-provenance workflowsdocs/specs/support_matrix.v0_29.jsonas the machine-readable support matrixdocs/specs/SUPPORT_MATRIX.mdas the human-readable support matrixnotebooks/12_dataset_to_downstream_workflow.ipynbnotebooks/13_candidate_to_split_provenance_workflow.ipynb
Milestone Status#
Milestone 0: COMPLETE
Milestone 1: COMPLETE
Milestone 2: COMPLETE
Milestone 3: COMPLETE
Milestone 4: COMPLETE
Milestone 5: COMPLETE
Milestone 6: COMPLETE
Authoritative scope:
docs/planning/V0_29_SCOPE.md
Public-Surface Audit#
Confirmed:
no
pdelie.reporting.summarize_workflow_readiness(...)no new runtime API
no new root export
no new PDE or numerical regime
no file loader, broad adapter, metadata inference engine, resampling API, multidimensional/nonuniform API, train/test policy, KS runtime API, neural/callable API, or operator API landed
Release Gate and Readiness#
Implemented:
tests/test_v0_29_release_gate.pyCI
v0_29-release-gatepackage metadata bump to
0.29.0Git-tag-only release-readiness docs; PyPI/TestPyPI remain deferred until
v1.0or later