@@ -12,8 +12,11 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
1212
1313## [ 1.8.0] — 2026-05-21
1414
15- Multi-phase architecture refactor + project-infrastructure round. No
16- public-API change; no numerical change. Three threads landed:
15+ Multi-phase architecture refactor + project-infrastructure round +
16+ external-review follow-up. No public-API change; one CLI default
17+ change (`` pybmodes windio --on-skip `` defaults to `` fail-on-data ``
18+ instead of silently warning — see Phase 4 below); no numerical
19+ change. Four threads landed:
1720
1821- ** Phase 1** — re-license (MIT → Apache 2.0), Sphinx documentation
1922 site on Read the Docs, governance + CI hardening, strict mypy /
@@ -32,6 +35,17 @@ public-API change; no numerical change. Three threads landed:
3235 (tower-specific platform-scalar parsers). Every public name
3336 is preserved; existing imports keep working through the
3437 `` __init__.py `` re-export layer.
38+ - ** Phase 4** — external-review hardening: ``pybmodes batch
39+ --patch`` gains the same dry-run / backup / output-dir safety
40+ contract that `` pybmodes patch `` has had since 1.0 (now with
41+ `` backup=True `` default for tree-wide mutation); `` run_windio ``
42+ gains an `` on_skip `` policy parameter that flips
43+ computational-skip failures from silent `` exit_code=0 `` to
44+ `` exit_code=1 `` by default; a new `` validation.yml `` GitHub
45+ Actions workflow enforces the published 0.01 % integration-test
46+ tolerance in CI by cloning the upstream OpenFAST / IEA-Task-37
47+ repositories on the fly, so the validation claim no longer
48+ depends on maintainer-local state.
3549
3650### Added
3751
@@ -202,6 +216,54 @@ public-API change; no numerical change. Three threads landed:
202216 a planned mixin-based split was rejected by Plan-agent review
203217 as architecturally hollow.
204218
219+ Phase 4 — external-review hardening
220+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
221+
222+ - ** `` run_batch `` safety contract** (Phase 4 PR D1, merged in #77 ).
223+ `` run_batch(..., patch=True) `` previously called `` patch_dat ``
224+ directly on every discovered side-deck. The per-deck loop now
225+ delegates to `` run_patch `` so the compute-before-write split +
226+ write-mode selection are reused unchanged. Three new parameters
227+ on `` run_batch `` plumbed through `` --dry-run `` / `` --backup `` /
228+ `` --no-backup `` / `` --output-dir `` on the CLI: `` dry_run ``
229+ (default `` False `` ), `` backup `` (** default `` True `` — new in
230+ 1.8.0** , since `` batch `` mutates a tree surfaced by recursive
231+ discovery, not a single hand-typed filename — single-deck
232+ `` run_patch `` keeps `` backup=False `` default), `` output_dir ``
233+ (per-deck destination namespaces on the deck's * relative path
234+ under root* to avoid stem collisions between sibling sub-trees,
235+ fix from Codex P1 review). Addresses external-review finding
236+ P1-3.
237+ - ** `` run_windio `` `` on_skip `` policy** (Phase 4 PR D2, merged in
238+ #78 ). Three policies: `` "warn" `` (legacy permissive),
239+ `` "fail-on-data" `` (** new default** — computational skips toggle
240+ `` exit_code=1 `` ; presentation + input skips warn), `` "fail" ``
241+ (strict — any skip fails). Each internal skip site is classified
242+ as `` data `` (blade composite reduction), `` presentation ``
243+ (Campbell / spectra plot rendering), or `` input `` (Campbell
244+ requested without a discovered ElastoDyn deck). CLI plumbing:
245+ `` pybmodes windio --on-skip {warn,fail-on-data,fail} `` .
246+ ** Behaviour change** : callers / automation that previously relied
247+ on `` run_windio `` returning `` exit_code=0 `` on blade-extraction
248+ failure now see `` exit_code=1 `` by default. Pass
249+ `` --on-skip warn `` (or `` on_skip="warn" `` library-side) for the
250+ pre-1.8.0 permissive default. Addresses external-review finding
251+ P1-2.
252+ - ** Validation workflow** (Phase 4 PR D3, merged in #79 ). New
253+ `` .github/workflows/validation.yml `` (`` workflow_dispatch `` +
254+ weekly Monday cron) clones the upstream OpenFAST r-test + IEA-
255+ Task-37 reference-turbine repositories from public GitHub and
256+ runs `` pytest -m integration --tb=short `` hard-fail (no exit-5
257+ tolerance, unlike the per-PR `` ci.yml `` ). The verifier-report
258+ artifact is uploaded with 90-day retention. The new
259+ `` [] `` badge on README + VALIDATION.md links to
260+ the workflow; the * Enforcement* paragraph in VALIDATION.md names
261+ the CI-validated coverage explicitly (NREL r-test family +
262+ IEA-Task-37 RWTs) and calls out the BModes CertTest 03/04 gap
263+ (BModes is a NREL download, not GitHub, so those cases stay
264+ maintainer-local enforcement). Addresses external-review
265+ finding P1-1.
266+
205267### Fixed
206268
207269- ** Blade Campbell labels for operating-only sweeps.** In
0 commit comments