Pre-Release Notes ================= Unreleased ---------- 0.5.0 architecture clean break ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - ``PinchProblem`` remains the strict mapping-in/result-out contract. Its signature, validation order, return structure, serialization, ordering, exceptions, and numerical behaviour are unchanged. - The package root exports exactly ``PinchProblem`` and ``PinchWorkspace`` as the high-level workflow entry points. Schemas, enums, resource helpers, and the main service remain with their concrete owners. - Business state, wire contracts, reusable optimisation, orchestration, engineering analysis, infrastructure adapters, and presentation now have explicit ``domain``, ``contracts``, ``optimisation``, ``application``, ``analysis``, ``adapters``, and ``presentation`` owners. - ``OpenPinch.classes``, ``OpenPinch.lib``, ``OpenPinch.services``, ``OpenPinch.utils``, and ``OpenPinch.streamlit_webviewer`` are removed. There are no aliases, forwarding facades, dynamic export barrels, pickle shims, or migration package. Old deep imports and Python pickles are not migrated. - Runtime stream segments, exchanger period states, exchanger area slices, process-MVR records, multiperiod HPR cases, dashboard state, graph build records, and HEN solver state remain private to their parent or service owner. - Optimisation is a reusable package-level capability. Heat-pump targeting crosses one explicit adapter; new services can reuse optimisation without importing heat-pump code. - HPR internal records are attribute-only, and HPR optimiser identifiers must exactly match ``dual_annealing``, ``cmaes``, ``bo``, or ``rbf_surrogate``. Obsolete helper-signature retries and historical optimiser spellings are not accepted. - ``StreamCollection`` supports current-version pickle round trips, including deterministic fallback for an unpicklable callable sort key. It does not repair state dictionaries produced by older package versions. - Internal type-only imports now resolve to the concrete configuration owner, total-site utility profiles forward the canonical period keyword, and invalid crossflow row counts raise an explicit validation error. - Tests now mirror observable owner layers. The external main contract is authoritative, architecture directions are AST-enforced, and CI measures seeded statement and branch coverage with Hypothesis seed ``20260715``. This is an intentional pre-1.0 clean break. No data migration, import migration, pickle migration, or compatibility layer is provided. Domain and input contracts ~~~~~~~~~~~~~~~~~~~~~~~~~~ This pre-release changes the following contracts without compatibility shims: - Values owned by a ``Stream`` and its segment records are read-only. Mutations use explicit stream assignment, indexed-value, or segment-update APIs. - Period weights use one validation policy: omitted trailing weights become ``1.0``; excess, non-finite, negative, and all-zero vectors are rejected. - Structured process-stream and nested thermal-profile inputs reject unknown fields. Process streams accept the canonical ``name`` and ``heat_capacity_flowrate`` spellings only. - Workspace bundles use schema version ``2`` and ``case_input``. Version ``1``, unknown versions, and the retired ``payload`` field are rejected. - Segmented process streams and utilities share the same semantic validation in reports and preparation, including parent aggregate consistency. - ``TargetInput.network`` accepts the exact mapping produced by ``HeatExchangerNetwork.model_dump(mode="json")`` and preserves it through a complete input JSON round trip. The transport contract rejects private solver and source metadata and does not automatically seed HEN synthesis. - HEN endpoint classifications now use ``StreamID`` values ``Process`` and ``Utility``. The retired lowercase endpoint-role enum and ``Unassigned`` endpoint values are not accepted. - ``StreamID`` is string-backed, keeping Python-mode HEN and canonical input mappings safe for direct JSON and workspace-bundle persistence. Private helper ownership ~~~~~~~~~~~~~~~~~~~~~~~~ - Private class helpers are grouped under owner-oriented packages for streams, values, collections, problem tables, problem orchestration, workspaces, and heat exchangers. - Runtime stream-segment, exchanger-period, and exchanger-area-slice record classes are parent-owned implementation details. Construct them through ``Stream`` and ``HeatExchanger`` mappings. The equivalent segment wire shape remains accepted through ``PinchProblem(...)``; direct schema imports are not compatibility-protected. - The former public record imports and their Python pickle paths are removed without aliases or compatibility shims. - Synthesis schemas now have concrete common, topology, method, task, and result owners. The compatibility-only ``methods``, ``tasks``, and ``results`` modules and the synthesis package re-export barrel are removed. Import concrete owner modules instead; old barrel-qualified pickle paths are unsupported. - Owner package ``__init__`` files remain import-free markers. The package root is the deliberate two-class workflow surface. The retired ``classes``, ``lib``, ``services``, ``utils``, and ``streamlit_webviewer`` package paths have no compatibility facades; advanced callers import concrete owner modules. - Process-MVR records, multiperiod HPR period cases, dashboard graph state, graph specifications/metadata, and HEN solver runtime records are private to their owning services. Concrete parent components, schemas, direct-MVR models, and HEN equation-model classes remain available as unsupported internals. Period-native PDM and utility constraints ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - PDM decompositions expose ordered ``period_targets`` with explicit period identities and indices. Clipped temperatures and active-stream flags are period-indexed; the retired singular target and clipped-temperature fields do not exist. - Each operating period uses its own utility targets and pinch temperature. Shared topology is the union of streams and matches active in any period, and a pinch side is solved when any period requires it. - Above- and below-pinch amalgamation retains every period's duties, temperatures, approach variables, split fractions, and explicit non-isothermal branch outlet temperatures. - Non-isothermal warm starts normalize hot split fractions across cold matches and cold split fractions across hot matches independently in every period. - Segmented utilities use local per-segment ``dt_cont`` values. The inlet uses the first segment contribution, the solved match outlet uses the traversed segment contribution, and an exact boundary uses the larger adjacent value. Period-native HEN results ~~~~~~~~~~~~~~~~~~~~~~~~~ - ``HeatExchanger`` retains shared topology, design area, and capital fields. Operational duty, activity, approaches, split fractions, and source/sink temperatures are stored in non-empty ordered ``period_states`` containing parent-owned period-state records. - The retired exchanger-level operating scalar fields do not exist. Use ``exchanger.state(period_id)``; omission is accepted only for an exchanger with exactly one period state. - Multiperiod duty, temperature, diagram, export, and controllability queries require ``period_id``. No implicit period-zero selection is provided. - Extraction walks every period array, retains matches active only outside the first period, and prefers explicit non-isothermal branch outlet temperatures. Solved branch split fractions keep downstream duty checks physically valid. Isolated summaries and HPR economics ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Multiperiod summary replay captures one baseline zone and solves every period against a fresh deep copy. The original zone object, cached results, and recorded targeting specification are restored after success or failure. - Shared simulated-HPR candidates are ranked by weighted operating cost plus weighted feasibility penalty plus maximum annualized capital cost. Weighted backend ``obj`` is used only for backends that provide no cost breakdown. - Weighted internal HPR summaries average operating fields, use the maximum capital, annualized-capital, compressor-capital, and heat-exchanger-capital fields, and recompute total annualized cost as weighted operating cost plus maximum annualized capital. Non-HPR fields retain weighted averaging.