diff --git a/AGENT_HANDOFF.md b/AGENT_HANDOFF.md
index 0c6580167..9146e1fcb 100644
--- a/AGENT_HANDOFF.md
+++ b/AGENT_HANDOFF.md
@@ -1,5 +1,43 @@
# AGENT_HANDOFF — Tools
+## 2026-08-11 PR #4342 current-parent propagation candidate
+
+This no-publish candidate keeps PR `#4342` on
+`feat/4274-regional-plan-io` with base `feat/4274-regional-surface-ui`.
+Exact current child `c1f47f2ef68b3db102da5416aaac17a40f675207` is the first
+parent and exact reviewed local #4339 candidate
+`db335937afc4b587d235eb705e315f577519c5e6` is the second parent of a
+normal no-ff merge. Child-owned canonical request import/export, bounded UTF-8,
+native atomic save, browser-qualified download, tests, and limitations remain
+intact while inheriting current editor, wire, regional-physics, and complete
+ground-model ancestry.
+
+The merge also resolves one cross-runtime compatibility edge without weakening
+the ground contract. The default shared canonical encoder still rejects floats
+or integers outside JavaScript's safe range. A separately named extended
+finite-float policy reuses the same recursive encoder only through the
+capability-observation facade; integers remain safe-range bounded and integral
+finite doubles such as `1e20` and `1e21` emit exact exponent-free tokens that
+match the TypeScript capability serializer. Non-finite values still fail
+closed.
+
+Local qualification is green: all `909` Rate-of-Closure Python tests, all
+`110` React files / `686` tests, and the complete Cargo workspace pass. The
+focused compatibility/regional-I/O slices pass `47` Python and `12` React
+tests. Pinned Ruff 0.14.10 check/format passes `17` changed Python files; pinned
+MyPy 1.13 and Bandit pass `12` changed production files. TypeScript,
+zero-warning ESLint, the 199-module Vite build, Rust format and warning-denied
+clippy, both 400- and 500-LOC changed-file gates, manifest/docs/blocking-gate/
+assertion/minimum-test governance, marker scans, and diff checks pass. An
+untouched manual-delivery UI test timed out once during the first concurrent
+full run, then passed alone and in the single complete rerun.
+
+No branch has been rebased, retargeted, rewritten, force-pushed, or published.
+Execution and playback, result interchange, measured calibration, model-input
+persistence, changing geometry or velocity, TypeScript/compiled regional
+physics, downstream parity, protected exact-head evidence, approval,
+dependency integration, and release remain open.
+
## 2026-08-11 PR #4339 current-parent propagation candidate
This no-publish candidate keeps PR `#4339` on
@@ -32,188 +70,16 @@ model-input persistence, changing geometry or surface velocity,
TypeScript/compiled regional physics, downstream parity, protected exact-head
evidence, approval, dependency integration, and release remain open.
-## 2026-08-11 PR #4339 structural helper repair candidate
-
-This local follow-up descends exact independently reviewed reconciliation
-candidate `eedad6d23b517eb4c99d4ba9000ff6555101099f`. Independent review found
-one publication blocker: the regional PyQt number-input helper accepted six
-parameters, above the campaign's mandatory four-parameter limit. RED-first
-tests now bind the helper's signature and all observable widget settings. A
-frozen `NumberInputSpec` validates finite positive step and finite ordered
-bounds before widget construction; the three-parameter helper preserves field
-names, values, units, ranges, increments, tooltips, and presentation order.
-
-Eight focused Python/PyQt tests and 25 focused React tests pass; the complete
-React suite passes all 108 files / 672 tests. Pinned Ruff check/format, MyPy on
-all six affected production modules, Bandit medium/high screening, TypeScript,
-zero-warning ESLint, documentation/manifest governance, changed-production,
-test-assertion, minimum-test, 500-LOC, and diff gates pass. Mandatory maxima
-are 400 module lines, 42 function lines, and three parameters. A broader
-Rate-of-Closure Python run reached the ten-minute workstation lifecycle bound
-without yielding an assertion failure; it is not counted as passing evidence.
-The monorepo-wide lane separately exposed unrelated baseline failures and
-xdist worker termination. No schema, digest, regional physics, UI behavior,
-PR base, protected evidence, or release boundary changes.
-
-## 2026-08-11 PR #4339 current-parent ancestry candidate
-
-The clean `feat/4274-regional-surface-ui` worktree normally merges exact
-published child `cbb9c0a6bdc6a50f59f7a661139b9d53e1892980` with exact newly
-published #4335 parent `9e01ccc3e891cc45907293751a192624195a77a5`,
-while preserving #4339's `feat/4271-regional-wire-contract` base. Production
-UI, contract, resolver, regional physics, and ground ancestry merge without
-conflict. Only SPEC, manifest, and handoffs are reconciled. Independent review,
-ordinary fast-forward publication, fresh protected CI/approval, dependency
-integration, and release remain required.
-
-## 2026-08-10 PR #4339 stale-validation invalidation follow-up
-
-Rendered exact-head browser QA found that a validated one-overlay readback
-remained visible after adding a second overlay. The broad PyQt6 suite also
-found missing hover hints on the new controls. PyQt6 and React now clear both
-canonical readback and prior validation state whenever any identity, interval,
-material, or overlay-row draft value changes; PyQt6 exposes the explicit
-"Changes not validated" pending state, and every PyQt6 interactive has a
-specific engineering-context tooltip. RED-first regression tests cover the
-dynamic-row path on both surfaces. Final local evidence is 870 Python/PyQt
-tests and 672 React tests passing; Ruff, format, MyPy, TypeScript, zero-warning
-ESLint, the 198-module production build, manifest/docs/file-size governance,
-and diff checks are clean. The known polynomial-generator empty-legend warning
-is unrelated. This changes no wire schema, provenance digest, physics, or
-persistence boundary; fresh protected CI is still required before merge.
-
-## 2026-08-11 Current regional-surface parent reconciled into PR #4335
-
-Open draft PR `#4335` retains branch `feat/4271-regional-wire-contract` and
-base `feat/4271-regional-surface-transitions`. Exact remote regional-wire child
-`9e01ccc3e891cc45907293751a192624195a77a5` is merged first and exact current
-regional-surface parent `5ac3c1f233de30dd42eeac57073cbdb149bde652`
-second by an ordinary no-ff merge. The child's Python/TypeScript wire schemas,
-canonical JSON/SHA-256 fixture, fail-closed parsing, Python resolver binding,
-tests, contracts, and limitations remain intact with both append-only handoff
-and specification histories.
-
-Focused local qualification is green: all `132` Python ground/regional-wire
-tests, `9` focused React regional/ground-contract tests, and all `137`
-`tools-core` Rust tests pass. TypeScript, zero-warning ESLint, the 190-module
-Vite build, Rust workspace format and warning-denied clippy, pinned Ruff 0.14.10
-across the six-file Python PR delta, pinned MyPy 1.13 and Bandit medium/high
-across four production files, the 500-LOC changed-file gate, manifest parsing
-plus all eight contracts, documentation governance, exact wire-tree
-preservation, history/marker, and diff checks pass.
-
-This candidate is unpublished and `not_released`. Changing geometry or
-velocity, internal transition-ledger export, regional UI, compiled or
-TypeScript regional physics, UpstreamDrift parity, protected exact-head CI,
-review, approval, dependency integration, and release remain open.
-
-## 2026-08-11 Current skid/roll parent reconciled into PR #4332
-
-Open draft PR `#4332` retains branch
-`feat/4271-regional-surface-transitions` and base
-`feat/4271-ground-skid-roll`. Exact remote regional-surface child
-`04ccf08dd990de1cd056a3420e67772773a4be2e` is merged first and exact current
-skid/roll parent `3f861c1faaa7455faee92eaa7f813174667208e0` second by an ordinary no-ff
-merge. The child's bounded coplanar overlays, exact transition splitting and
-evidence, regional production, tests, fixtures, contracts, and limitations
-remain intact with both append-only handoff and specification histories.
-
-Focused local qualification is green: all `121` Python ground/regional tests,
-`20` focused React ground-contract/transfer tests, and all `137` `tools-core`
-Rust tests pass. TypeScript, zero-warning ESLint, the 189-module Vite build,
-Rust workspace format and warning-denied clippy, pinned Ruff 0.14.10 across the
-14-file Python PR delta, pinned MyPy 1.13 and Bandit medium/high across 12
-production files, the 500-LOC changed-file gate, manifest parsing plus all
-eight contracts, documentation governance, exact regional-tree preservation,
-history/marker, and diff checks pass.
-
-This candidate is unpublished and `not_released`. Changing normals,
-discontinuous geometry or surface velocity, regional UI, compiled regional
-physics, UpstreamDrift parity, protected exact-head CI, review, approval,
-dependency integration, and release remain open.
-
-## 2026-08-11 Current impact/bounce parent reconciled into PR #4304
-
-Open draft PR `#4304` retains branch `feat/4271-ground-skid-roll` and base
-`feat/4270-ground-impact-bounce`. Exact remote skid/roll child
-`0ea6740965068542e9d8c7449e06ec07d88969e0` is merged first and exact current
-impact/bounce parent `62beb3e1aa951645fd556a53f9cbae4bb46c47e5`
-second by an ordinary no-ff merge. The child's arbitrary-plane skid, pure roll,
-rolling resistance, rest, edge localization, strict result composition,
-passive ledgers, fixtures, tests, and limitations remain intact with both
-append-only histories.
-
-Local verification is green: `154` focused ground/flight physics and contract
-tests plus all eight campaign-manifest tests pass, as do all `137` `tools-core`
-Rust tests. Pinned Ruff 0.14.10 check/format covers all 18 PR-delta Python files;
-pinned MyPy 1.13 and Bandit medium/high cover all 12 production files. Rust
-format and warning-denied clippy, manifest parsing/validation, documentation
-governance, exact skid/roll-tree preservation, marker/history, and diff checks
-pass.
-
-This local candidate is not published or released. Regional/changing-normal
-surfaces, deformation, torsional damping, roll-to-skid transitions, UI,
-compiled physics, protected exact-head CI, review, approval, downstream
-integration, and release remain open.
-
-## PR #4302 corrected-flight-transfer propagation
-
-Draft PR #4302 remains on `feat/4270-ground-impact-bounce` with unchanged base
-`feat/4269-flight-ground-transfer`. Exact corrected #4288 parent
-`247215422a6d4b677552955b4923bc609a553259` is incorporated by the normal merge
-containing this handoff. The child preserves its passive restitution/Coulomb
-sphere-plane impulse, deterministic repeated ballistic hops, exact physical
-contact, capture-to-skid handoff, cancellation/failure semantics, and airborne
-segment evidence while inheriting the corrected transfer ancestry, deterministic
-workspace timestamps, and canonical `swing_sim` import identity. No branch was
-rebased, retargeted, rewritten, or force-pushed.
-
-The slice remains partial and `not_released`: issue #4271 retains skid, roll,
-rest, total distance, and final `GroundSimulationResult`; terrain deformation,
-UI execution, TypeScript bounce physics, compiled Rust/PyO3/WASM bounce parity,
-and UpstreamDrift adapters remain excluded. Protected CI, independent review,
-and dependency-ordered collapse remain separate release gates.
-
-Merged-tree validation is `987` Python tests, `106` React files / `661` tests,
-and the complete `tools-core` Rust suite at `137` tests (`111` unit, `20`
-transfer, `6` wire). The affected cross-version suite is also `146` tests on
-real CPython 3.10.20. The 189-module Vite production build, TypeScript,
-zero-warning ESLint, Ruff check/format across 90 files, pinned mypy 1.13 across
-all 17 ground and nine transfer production modules, Rust workspace format plus
-warning-denied `tools-core` clippy, campaign-manifest validator plus eight
-contracts, documentation governance, 11-file 500-LOC budget, marker scan, and
-diff checks are clean. Hosted checks and review apply to the new exact merge
-head only.
-
-
-## PR #4288 corrected-ground propagation
-
-Draft PR #4288 remains on `feat/4269-flight-ground-transfer` with unchanged
-base `feat/4268-ground-contract`. Exact corrected #4285 parent
-`788aa547651a3685a363ea401824a5d81477bafb` is incorporated by the normal merge
-containing this handoff. The child preserves its signed terminal state,
-physical sphere/terrain contact brackets, strict provenance, and qualified
-Python/TypeScript/Rust/PyO3/WASM transfer while inheriting deterministic
-workspace timestamps and canonical `swing_sim` import identity. No branch was
-rebased, retargeted, rewritten, or force-pushed.
-
-This propagation adds no bounce, skid, roll, terrain response, total distance,
-or UI execution. Protected CI, independent review, and dependency-ordered
-collapse remain separate release gates.
-
-Merged-tree validation is `951` Python tests, `106` React files / `661` tests,
-and `26` focused Rust transfer/wire tests. The affected cross-version suite is
-also `110` tests on real CPython 3.10.20. The 189-module Vite production build,
-TypeScript, zero-warning ESLint, Ruff check/format across 82 files, pinned mypy
-1.13 across the six-file transfer and 13-file parent production namespaces,
-Rust workspace format plus warning-denied `tools-core` clippy, campaign-manifest
-validator plus eight contracts, documentation governance, 13-file 500-LOC
-budget, marker scan, and diff checks are clean. Hosted checks and review apply
-to the new exact merge head only.
+## 2026-08-11 PR #4342 append-only preservation repair
-> Update this file in every implementation commit and every push to `main`.
-> Last updated: 2026-08-11.
+Independent audit of local merge `e7fedfb18de1550eed3484ed2fc99d0baaecdca1`
+found that three older parent ancestry sections had been summarized instead of
+retained verbatim. This docs-only follow-up restores the full parent text below
+without changing production code, tests, schemas, manifest state, PR base, or
+release claims. The exact parent sections and SPEC rows are now governed by
+byte-for-byte comparison against
+`d21741e312b849a63f73cabf351a15d9de80fb94`.
## 2026-08-11 PR #4335 current-parent ancestry candidate
@@ -287,67 +153,6 @@ now records open PR #4332 at its still-published child head and open PR #4304
at its exact newly published parent head; neither record claims protected or
main-release evidence.
-## 2026-08-11 Current flight-transfer parent reconciled into PR #4302
-
-Open draft PR `#4302` retains branch `feat/4270-ground-impact-bounce` and base
-`feat/4269-flight-ground-transfer`. Exact remote bounce child
-`cf6e72bad98e5f36f782254942e6895b8b71e670` is merged first and exact current
-flight-transfer parent `c39297d37a17d5d8d3520ed62c5563cdcc609cab` second by an
-ordinary no-ff merge. Passive impact/restitution/friction, deterministic
-repeated bounce, exact contact, capture-to-skid handoff, bounded failure and
-cancellation, and all transfer production, tests, fixtures, and limitations
-remain intact. Both append-only histories are retained.
-
-The exact PR delta also receives the three AST-equivalent layouts required by
-the repository-pinned Ruff 0.14.10 formatter; no analysis, persistence, or
-contract assertion behavior changes.
-
-Local verification is green: `1129` Rate/ground/flight Python tests, `25`
-focused React transfer tests, and all `137` `tools-core` Rust tests pass.
-TypeScript, zero-warning ESLint, the 189-module Vite build, Rust format and
-warning-denied clippy, pinned Ruff 0.14.10 check/format across the 14-file PR
-delta, pinned MyPy 1.13 across eight production files, Bandit medium/high,
-campaign-manifest parsing, documentation preservation, and diff checks pass.
-
-This local candidate is not published or released. Skid, roll, rest, total
-distance, final ground results, UI, TypeScript bounce physics, and compiled
-bounce runtimes remain open, as do protected exact-head CI, independent review,
-approval, dependency integration, and release.
-
-## PR #4285 workspace timestamp propagation
-
-Draft PR #4285 remains on `feat/4268-ground-contract` with unchanged base
-`feat/4197-capability-observer`. Exact corrected #4282 carrier
-`5f77af4add23547a21cc3fabce98ae9ad4260427` is incorporated through the normal
-merge containing this handoff. No branch was rebased, retargeted, rewritten,
-or force-pushed.
-
-The child retains its strict, UI-neutral flight-to-ground schemas, canonical
-fixture, migrations, legacy-result adapter, explicit dependency, and pinned
-typing repairs while inheriting the deterministic Python 3.10-3.12 UTC parser
-and the corrected variation, scalar, wind, capability, and campaign-release
-ancestry. This merge does not claim bounce, skid, roll, terrain profiles,
-total distance, UI execution, or Rust/WASM delivery. Protected CI, review, and
-normal descendant propagation remain separate release gates.
-
-Exact-head CI on the preceding child head exposed an actionable collection
-defect after installing the package: embedded `src.shared.python.swing_sim`
-tests and canonical `shared.python.swing_sim` imports could load distinct
-package trees, making the ground and impact subpackages unavailable by import
-order. The shared alias registry now coalesces `swing_sim`; an isolated RED/GREEN
-identity contract and both affected public-API suites pin the correction. The
-separate file-size job was cancelled during checkout and did not execute its
-budget check, so it remains infrastructure evidence rather than a source
-failure.
-
-Merged-tree evidence is `915` Rate/ground/impact Python tests, the `12`-test
-shared-alias architecture suite, `28` focused ground/impact/alias tests on
-CPython 3.12, `28` direct compatibility tests on real CPython 3.10.20, and
-`104` React files / `642` tests. The 188-module Vite build, TypeScript,
-zero-warning ESLint, Ruff, format, pinned mypy 1.13, campaign-manifest
-validation plus eight contracts, documentation governance, the 44-file
-500-LOC budget, conflict-marker scan, and diff checks are clean.
-
## 2026-08-11 PR #4304 current-parent ancestry candidate
The clean dedicated `feat/4271-ground-skid-roll` worktree first fast-forwarded
@@ -370,6 +175,180 @@ the official changed-file 500-LOC budget, and mandatory production limits of
local merge is a PUBLISH candidate for independent review only; protected
exact-head CI, approval, normal child propagation, and publication remain open.
+
+## 2026-08-11 PR #4342 current-parent reconciliation candidate
+
+The clean `feat/4274-regional-plan-io` worktree normally merges exact
+published PR #4342 child `8e1c7ccd99a7c4886c5fb9ccc7e4d94a6d7e3833`
+with exact newly published PR #4339 parent
+`d21741e312b849a63f73cabf351a15d9de80fb94` as its second parent. PR #4342
+continues to target `feat/4274-regional-surface-ui`; neither branch is rebased,
+retargeted, rewritten, force-pushed, or published by this reconciliation.
+The merge preserves strict regional request import/export together with the
+parent's frozen engineering-number specification and bounded helper.
+
+The child widget module now delegates its canonical-precision controls to that
+shared three-parameter helper while retaining the inclusive cross-runtime safe
+number bounds and eleven-decimal presentation required by its I/O contract.
+Merged-tree qualification is 53 focused Python/PyQt/shared-ground tests and 14
+focused React tests passing. Pinned Ruff 0.14.10 check/format, MyPy 1.13 over
+all ten affected production modules, Bandit medium/high screening, TypeScript,
+zero-warning ESLint, and the 199-module production build pass. Campaign
+manifest validation and all eight manifest tests, documentation and tool
+manifest governance, changed-Python, minimum-test, exact-diff assertion,
+500-LOC, parent/child diff, and whitespace gates pass. Mandatory structural
+maxima are 396 module lines, 40 function lines, and three parameters.
+The local merge is not protected or release evidence. Independent review,
+ordinary fast-forward publication, fresh protected CI/approval, dependency
+integration, and release remain required.
+
+## 2026-08-11 PR #4339 structural helper repair candidate
+
+This parent follow-up descends exact independently reviewed reconciliation
+candidate `eedad6d23b517eb4c99d4ba9000ff6555101099f`. Independent review found
+one publication blocker: the regional PyQt number-input helper accepted six
+parameters, above the campaign's mandatory four-parameter limit. RED-first
+tests bind the helper's signature and all observable widget settings. A frozen
+`NumberInputSpec` validates finite positive step and finite ordered bounds
+before widget construction; the three-parameter helper preserves field names,
+values, units, ranges, increments, tooltips, and presentation order.
+
+Eight focused Python/PyQt tests and 25 focused React tests pass; the complete
+React suite passes all 108 files / 672 tests. Pinned Ruff check/format, MyPy,
+Bandit medium/high screening, TypeScript, zero-warning ESLint,
+documentation/manifest governance, changed-production, test-assertion,
+minimum-test, 500-LOC, and diff gates pass. Mandatory maxima are 400 module
+lines, 42 function lines, and three parameters. No schema, digest, regional
+physics, UI behavior, PR base, protected evidence, or release boundary changes.
+
+## 2026-08-11 PR #4339 current-parent ancestry candidate
+
+The clean `feat/4274-regional-surface-ui` worktree normally merged exact
+published child `cbb9c0a6bdc6a50f59f7a661139b9d53e1892980` with exact published
+#4335 parent `9e01ccc3e891cc45907293751a192624195a77a5`, while preserving
+#4339's `feat/4271-regional-wire-contract` base. Production UI, contract,
+resolver, regional physics, and ground ancestry merged without conflict; only
+SPEC, manifest, and handoffs were reconciled. Independent review, ordinary
+publication, protected exact-head CI/approval, dependency integration, and
+release remained open.
+
+## 2026-08-11 PR #4342 delta-MyPy follow-up
+
+Protected CI on exact PR #4342 head
+`cffe349ac0a8054f1d168cb36684fd00bc5f8a49` identified one redundant `bool`
+cast in the regional atomic-write adapter under the Linux delta-MyPy gate. The
+cast is removed; the typed helper's direct Boolean return is preserved. This
+changes no wire bytes, validation, file semantics, UI behavior, or physics.
+Focused persistence tests and the CI-equivalent pinned MyPy command pass
+locally; fresh protected CI/review and dependency ordering remain required.
+
+## 2026-08-11 regional request I/O protected publication
+
+Branch `feat/4274-regional-plan-io` is published normally as draft PR
+[#4342](https://github.com/D-sorganization/Tools/pull/4342), targeting exact
+PR #4339 branch `feat/4274-regional-surface-ui` at parent head
+`cbb9c0a6bdc6a50f59f7a661139b9d53e1892980`. Its reviewed implementation
+head is `d748e7a5ef3da5e6ce7737ff6829e0f14665fe97`; publication commits change
+no runtime behavior. Protected CI, independent review, issue #4274, parent
+ordering, integration, and release remain open.
+
+## 2026-08-11 bounded regional request read follow-up
+
+Independent review of local safe-number commit
+`10c394f6b1fd2927e7f3b1f96cc097cae6bfd380` found that native request import
+checked file size with `stat()` and then performed a separate unbounded text
+read. A concurrently grown or replaced file could therefore allocate beyond
+the 1 MiB wire cap before the strict parser rejected it.
+
+Native import now opens one binary handle, reads at most the wire cap plus one
+sentinel byte, rejects overflow, strictly decodes UTF-8, and only then delegates
+to the unchanged canonical v1 parser. Tests simulate content growth after the
+metadata check and reject invalid UTF-8 explicitly. The complete regional and
+atomic persistence set is 28 tests passing. This changes no schema, digest,
+physics, browser behavior, or write semantics. Static and governance evidence
+is recorded in this commit: Ruff, Ruff format, Black, focused MyPy, manifest,
+module-size, documentation-governance, and diff checks pass. The child remains
+local and unprotected.
+
+## 2026-08-11 regional request I/O safe-number follow-up
+
+Independent review of local commit `e39edf4b50b1fb9811b0032bec4758c7a08c9b74`
+found two cross-runtime representation gaps. The PyQt6 precedence spin box
+silently narrowed otherwise valid v1 integers above 1,000,000, and Python
+accepted integer-valued wire numbers above JavaScript's exact safe range.
+
+The native editor now uses an exact decimal integer entry for precedence and
+preserves every v1 value from zero through 9,007,199,254,740,991 without a
+floating-point conversion. Shared Python canonical-number and ground-record
+validation now reject magnitudes outside that same range, matching React while
+retaining all finite fractional values inside it. PyQt6 floating-point editors
+publish the same bounds. Regression coverage pins exact maximum-precedence
+open/save round-trip and matched native/browser refusal of unsafe material
+numbers. This changes no schema version, provenance algorithm, physics, or
+browser filesystem limitation. Final local evidence is 132 shared ground tests,
+21 regional editor/I/O tests, five atomic-workspace tests, 23 focused React
+tests, the whole-shell tooltip sweep, and eight manifest tests passing. Ruff,
+Ruff format, Black, focused MyPy, TypeScript, zero-warning ESLint, the 199-module
+production build, module and changed-file size budgets, documentation
+governance, and diff checks pass. The child remains local and unprotected.
+
+## 2026-08-10 PR #4339 stale-validation invalidation follow-up
+
+Rendered exact-head browser QA found that a validated one-overlay readback
+remained visible after adding a second overlay. The broad PyQt6 suite also
+found missing hover hints on the new controls. PyQt6 and React now clear both
+canonical readback and prior validation state whenever any identity, interval,
+material, or overlay-row draft value changes; PyQt6 exposes the explicit
+"Changes not validated" pending state, and every PyQt6 interactive has a
+specific engineering-context tooltip. RED-first regression tests cover the
+dynamic-row path on both surfaces. Final local evidence is 870 Python/PyQt
+tests and 672 React tests passing; Ruff, format, MyPy, TypeScript, zero-warning
+ESLint, the 198-module production build, manifest/docs/file-size governance,
+and diff checks are clean. The known polynomial-generator empty-legend warning
+is unrelated. This changes no wire schema, provenance digest, physics, or
+persistence boundary; fresh protected CI is still required before merge.
+
+> Update this file in every implementation commit and every push to `main`.
+> Last updated: 2026-08-11.
+
+## 2026-08-10 issue #4274 canonical regional request I/O local child
+
+Local branch `feat/4274-regional-plan-io` started directly from published PR
+#4339 head `a9ace5052bcd54b78f79b62d5d9ac26debedb4b1`, then fast-forwarded
+normally to corrected exact parent `cbb9c0a6bdc6a50f59f7a661139b9d53e1892980`.
+The parent's stale-validation invalidation and tooltip follow-up are preserved.
+This child has not been pushed, opened as a PR, reviewed, merged, or released.
+
+The matched Ground Surfaces editors now import and export the canonical
+`ground-regional-material-plan-request/v1` document. PyQt6 uses native Open
+and Save As dialogs plus a shared flush/fsync/atomic-replace UTF-8 writer;
+cancel is a no-op, failed reads and writes preserve the last-known-good editor
+or file, and the recent path advances only after success. React validates a
+bounded browser File before committing state and downloads exact canonical
+bytes while revoking its object URL. Browser filesystem limitations are
+explicit, and workspace persistence remains separate.
+
+Import accepts only editor producer/provider v1 evidence, the fixed target
+frame origin/downrange axis, and one to eight rows. It never relabels external
+evidence. An unchanged import round-trips the exact request and provenance;
+after any edit, validation binds a fresh draft digest. No measured calibration
+is synthesized and neither path executes physics.
+
+RED-first coverage now includes exact-byte round-trip, native cancel and
+atomic rollback, corruption, duplicate keys, oversize input, unsupported
+producer/axis qualification, stale-provenance rebinding, transactional PyQt6
+population, browser rollback, URL cleanup, and pre-allocation size rejection.
+Focused evidence is 25 Python/PyQt tests and 12 React tests passing. With
+adjacent wire and manifest coverage, 44 Python and 16 React tests pass.
+Focused MyPy, Ruff, TypeScript, zero-warning ESLint, the 199-module production
+build, release-manifest validation, and module budgets are clean.
+
+Issue #4274 remains open. Measured calibration, workspace model-input
+persistence, execution/playback, result interchange, visualization, changing
+geometry, compiled regional physics, downstream parity, protected CI/review,
+integration of this child into the protected stack, and release remain explicit
+gaps.
+
## 2026-08-10 issue #4274 matched regional surface editor local child
Local branch `feat/4274-regional-surface-ui` started from published PR #4335
@@ -544,751 +523,6 @@ All `115` ground tests, Ruff, formatting, a finding-free local scan of the
affected file, documentation governance, the `370`-line source-size check,
and diff gates pass before an ordinary guarded fast-forward publication.
Fresh protected CI and review remain required.
-## 2026-08-11 Current ground parent propagated into PR #4288
-
-Open draft PR `#4288` retains branch `feat/4269-flight-ground-transfer` and base
-`feat/4268-ground-contract`. Exact remote transfer child
-`df716ac740beb9d47dced66f867dc3dde1fa5367` is merged first and exact current
-ground-contract parent `584e4e53a7990053a346938c4e45538786887ec7`
-second by an ordinary no-ff merge. Flight-to-ground production, tests, fixtures,
-cross-runtime contracts, Rust/PyO3/WASM integration, and explicit limitations
-remain intact. Only append-only handoff/SPEC aggregation conflicts require
-resolution; every dated record from both histories is retained. Focused gates
-pass 85 Python contract/transfer tests, 25 React tests, and 137 Rust library and
-transfer/wire tests. Pinned Ruff 0.14.10 covers all 13 PR-delta Python files,
-pinned MyPy 1.13 covers nine production files, and Bandit reports no medium/high
-findings. TypeScript, exact-delta ESLint, the 189-module web build, Rust format,
-docs, strict manifest, diff, exact transfer-tree, and both-parent preservation
-checks pass. Publication, protected exact-head CI, review, approval, and release
-remain open.
-
-## 2026-08-11 PR #4288 append-only history preservation repair
-
-This documentation-only follow-up to exact local candidate
-`1eb4188ff1a87a3d8e9a55aeca68194ca04e0bb4` restores the parent handoff
-sections and specification rows omitted during conflict resolution. It also
-repairs the interleaved rate-of-closure handoff paragraph without changing
-production code, tests, schemas, the campaign manifest, merge topology, or PR
-#4288's `feat/4268-ground-contract` base. Publication, protected exact-head CI,
-approval, dependency integration, and release remain open.
-
-## 2026-08-11 PR #4288 current-ground-parent ancestry candidate
-
-The clean `feat/4269-flight-ground-transfer` reconciliation starts from exact
-published child `afb1bdcfc6701caaf1f7bc3497a6a37dd9698c14` and normally merges
-exact newly published #4285 parent
-`e09ab96280cab363b36bd0e7db4a3cd064dc2527` second, while preserving #4288's
-`feat/4268-ground-contract` base. The child's bounded TypeScript integrator,
-signed terminal angular state, physical sphere/terrain contact, and cross-runtime
-transfer remain authoritative; the parent's split kinetics, plotting catalog,
-strict ground contract, and current wind/capability ancestry are retained.
-Seven surviving child-owned Python files are normalized with pinned Ruff
-0.14.10; this mechanical repair changes no AST. The TypeScript flight facade
-also preserves the exact child program with repository-standard line endings.
-Independent review, ordinary fast-forward publication, fresh protected CI,
-approval, dependency integration, and release remain open.
-
-> Update this append-only handoff in every implementation commit and every push
-> to `main`.
-> Last updated: 2026-08-11
-
-## 2026-08-11 Current capability carrier propagated into PR #4285
-
-- Open draft PR `#4285` retains branch `feat/4268-ground-contract` and base
- `feat/4197-capability-observer`. Exact remote child
- `e09ab96280cab363b36bd0e7db4a3cd064dc2527` is the first parent and exact
- published capability-observer carrier
- `d0b827667e61f0583e1dad0b3cbbca6819624d3c` is merged second by an ordinary
- no-ff merge. No branch is rebased, retargeted, force-pushed, or rewritten.
-- Ground-contract production, tests, schemas, fixtures, dependencies, and
- fail-closed limitations remain child-owned and intact. Only the four durable
- handoff/SPEC files conflict; their dated records from both parents are
- retained while the parent contributes the current wind/capability and release
- ancestry.
-- Focused verification is green: 214 strict-ground, impact, PyQt layout/GUI,
- kinetics, capability, wind, and manifest tests pass. Pinned Ruff 0.14.10
- checks/formats all 27 PR-delta Python files, pinned MyPy 1.13 accepts all 20
- production files, and Bandit reports no medium/high findings. Docs governance,
- strict campaign-manifest validation, diff hygiene, exact child ground-tree
- preservation, and both-parent handoff/SPEC preservation pass.
-- This is a bounded local audit. Publication, protected exact-head CI, review,
- approval, and normal downstream propagation into #4288 remain open.
-
-## 2026-08-11 Current #4282 ancestry reconciled into PR #4285
-
-- Draft PR `#4285` retains branch `feat/4268-ground-contract` and base
- `feat/4197-capability-observer`. Exact remote child
- `7a38b9838d743e051a6900620c4d6e754582aa89` is the first parent; exact
- published workflow/base head `b2baf6ef615b0d756a86ac4ca7eef2fc583210ee`
- is merged second. The latter contains merged #4283 head
- `9bbb98e16e435a0d4c74153b909f2ebfefbbce7a`, so dependency order is
- preserved without rebase, retarget, force-push, or parent rewrite.
-- The strict flight-to-ground schemas, migrations, fixture, legacy adapter,
- dependency declarations, and Python 3.10 compatibility remain intact. The
- inherited parent adds its current wind/capability stack, Ground/Tee parity,
- split kinetics facade, and pinned formatting repairs.
-- The only source conflict was the child's formatting-only pre-split kinetics
- hunk; it resolves wholly to the validated parent facade. Four append-only
- handoff/SPEC histories are retained and the campaign manifest records the
- exact published heads that this unpublished candidate composes.
-- The child-owned scalar extractor's required `float` narrowing made the
- 459-line plotting registry part of the effective delta. Ordered catalog data
- now lives in small private scalar/series collaborators; the public catalog is
- 61 lines and every changed production module/function/signature satisfies
- the strict 400-line/50-line/four-parameter limits without changing keys,
- order, extractors, units, or public objects.
-- Local verification passes the complete 1,539-test Rate/shared-swing Python
- matrix with one explicit optional Rust-wheel skip, all 648 React tests across
- 106 files, TypeScript, zero-warning ESLint, the 188-module Vite production
- build, and 12 `swing-core` Rust tests. Focused ground/parity/kinetics/wind/
- manifest and catalog/plot suites pass 146 and 57 tests respectively.
-- This is a local publication candidate only. Independent review, ordinary
- publication, fresh exact-head protected CI, required approval, and normal
- downstream #4288 propagation remain mandatory.
-
-## 2026-08-11 merged #4283 carrier receives current #4282
-
-- PR `#4283` is already merged, but its preserved head branch
- `feat/4197-capability-observer` remains the live base of open draft PR `#4285`.
- Exact remote/local carrier child
- `b2baf6ef615b0d756a86ac4ca7eef2fc583210ee` is merged first with exact newly
- published #4282 head `3faf9e9493c9ba37168d9f65ab10cafeedc2a72f`
- second by a normal no-ff merge. No PR is reopened, retargeted, or merged, and
- no branch history is rewritten.
-- Because the carrier child is already the first parent of #4282, the source
- merge is conflict-free and reproduces the exact #4282 implementation while
- preserving the complete capability-observer history. This carrier record is
- the only intentional tree delta from #4282.
-- Focused validation is green: 86 Python/PyQt capability, wind, and campaign-
- manifest tests pass, as do all 86 tests in 12 focused React capability/wind
- suites. React type-check, zero-warning lint, and the production build pass.
- Docs governance, strict campaign-manifest validation, and exact-parent diff
- hygiene pass. The exact tree delta from #4282 contains documentation only, so
- changed-Python Ruff/MyPy/Bandit gates are not applicable.
-- Publication is explicitly outside this bounded audit;
- protected current-head checks and ordinary dependency propagation into #4285
- remain separate future actions.
-
-## 2026-08-11 current scalar-adapter propagation into wind workflow PR #4282
-
-- PR `#4282` remains on `feat/4199-wind-workflow`, based on
- `feat/4199-wind-scalar-adapter`. Exact published child
- `b2baf6ef615b0d756a86ac4ca7eef2fc583210ee` is merged first with exact newly
- published parent `9321c1d2e091b8c7e5a4a83aa9ad726290e7fb5a` second by a
- normal merge; no rebase, retarget, force-push, or parent rewrite is used.
-- All implementation and test paths merge automatically. The child responsive
- PyQt6/React wind workflow, execution/progress/cancellation, persistence,
- export, consolidated capability stack, and strict campaign manifest remain
- authoritative while inheriting the parent's current wind scalar-adapter,
- variation, workspace, launch-monitor/D-plane, split-kinetics, and Qt repairs.
- Only append-only handoffs and SPEC conflict textually; both histories remain.
-- Focused pre-commit regression is green: all 94 focused Python/PyQt wind,
- responsive-layout, navigation, playback, and manifest tests pass, and all 44
- tests in eight focused React wind/responsive suites pass. Docs governance and
- strict campaign-manifest generation/validation also pass.
-- Exact post-commit PR-delta gates are also green: pinned Ruff 0.14.10 checks
- and formats all 57 changed Python files, pinned MyPy 1.13.0 accepts all 38
- changed production files, and pinned Bandit 1.7.7 finds no medium/high issues
- in 37 scanned source files. The 500-LOC budget, changed-Python policy,
- minimum-test contract, changed-test assertions, diff hygiene, React
- type-check, React lint, and production web build all pass.
-- This candidate remains local pending independent review, ordinary publication,
- protected exact-head CI, unresolved-thread checks, and dependency order.
-
-## 2026-08-11 Exact #4281 parent propagation into PR #4282
-
-- Draft PR `#4282` remains on `feat/4199-wind-workflow`, based on
- `feat/4199-wind-scalar-adapter`. Exact remote child
- `29e15d6ff631f7f30afcc745be783f2e716d7dcf` normally merges exact published
- parent `a7dce5f89b483303938f518b74b4028a1c68ba81` in child-first order without
- rebase, reset, retarget, force-push, or parent rewrite.
-- The responsive PyQt6/React wind workflow and consolidated capability stack
- remain intact while inheriting the parent's split kinetics facade, Ground/Tee
- parity, scalar-adapter module/parameter repair, and complete prior stack.
-- The sole source conflict is the child's obsolete formatting-only edit to the
- pre-split kinetics monolith; the validated parent facade is authoritative.
- Four documentation conflicts retain both append-only histories. Seven
- child-owned files require the pinned Ruff formatter before publication.
-- The exact skipped-import MyPy profile makes the facade cache suppression
- redundant; an explicit `KineticsSeries | None` cast preserves the runtime
- object while satisfying the static boundary without an ignore.
-- Local evidence is 74 focused Python/PyQt wind, kinetics, and Ground/Tee
- tests; 29 focused React tests; and 8 campaign-manifest tests. TypeScript,
- focused zero-warning ESLint, Ruff check/format, pinned MyPy 1.13, Bandit's
- medium/high threshold, strict wind module/signature/function budgets,
- manifest, documentation, policy, SPEC, and diff gates pass.
-- This is a local reconciliation candidate. Independent review, fresh
- exact-head protected CI, unresolved-thread checks, dependency order, and
- ordinary publication remain required.
-## 2026-08-11 current variation propagation into wind PR #4281
-
-- PR `#4281` remains on `feat/4199-wind-scalar-adapter`, based on
- `feat/4144-variation-export-continuation`. Exact published child
- `a7dce5f89b483303938f518b74b4028a1c68ba81` is merged first with exact newly
- published parent `e6c7460a01082631565fb9ed48aa32538bd7772c` second by a
- normal merge; no rebase, retarget, force-push, or parent rewrite is used.
-- All implementation and test paths merge automatically. The child
- Python/TypeScript scalar-ensemble, deterministic-scenario, wind-strategy
- adapter, and strict module-budget behavior remain authoritative while
- inheriting the parent's current variation, workspace, launch-monitor/D-plane,
- split-kinetics, and Qt typing repairs. Only append-only handoffs and SPEC
- conflict textually; both histories remain below.
-- Focused pre-commit regression is green: all 77 focused wind/variation Python
- tests pass, and all 20 tests in the five focused React wind/variation suites
- pass.
-- Exact post-commit PR-delta gates are also green: pinned Ruff 0.14.10 checks
- and formats all five changed Python files, pinned MyPy 1.13.0 accepts all
- three changed production files, and pinned Bandit 1.7.7 finds no issues in
- those three files. Both 500- and strict 400-LOC budgets, docs governance,
- changed-Python policy, minimum-test contract, changed-test assertions, diff
- hygiene, React type-check, React lint, and the production web build all pass.
- The manifest artifact/checker/test do not exist on either side of this
- pre-manifest stack, so that later release gate is structurally not applicable.
-- This candidate remains local pending independent review, ordinary
- publication, protected
- exact-head CI, unresolved-thread checks, and dependency order.
-## 2026-08-11 PR #4281 wind adapter module-budget repair
-
-- The 403-line `wind_strategy_plot_adapter.py` blocker is repaired by moving
- request/analysis validation into the private
- `_wind_strategy_plot_validation.py` collaborator. The public adapter is now
- 252 lines and the validator is 213 lines; both are below the mandatory
- 400-line ceiling.
-- The scenario validator accepts the scenario plus one frozen, slotted
- expectation object. No production function exceeds four parameters or 50
- lines.
-- `build_wind_strategy_plot_dataset`, `WIND_STRATEGY_*` exports, validation
- messages, variable/stage/category/cohort order, row identity, scalar values,
- availability, attributes, and the no-flight-rerun boundary are unchanged.
-- This is a local candidate only. Independent review, fresh exact-head
- protected CI, unresolved-thread checks, dependency order, and ordinary
- publication remain required before merge or release.
-
-## 2026-08-11 reviewed variation parent propagation into wind PR #4281
-
-- Exact remote wind child `247046d55afcad3e6cd4f8029f854856c427f59c`
- normally merges exact reviewed variation parent
- `3337945699966b63cb5cd8e52d7c3b194315e911` in child-first order. PR base,
- stack topology, and both histories remain intact; no rebase, reset, retarget,
- force-push, or parent rewrite is used.
-- Python/TypeScript scalar-ensemble and wind-strategy plot-adapter behavior is
- unchanged while inheriting the parent's variation/export UI, kinetics split,
- Ground/Tee parity, workspace/toolstrip, and Ruff-normalized repairs. The sole
- feature-code conflict was obsolete monolithic kinetics and is resolved to the
- validated parent `pendulum.sample(...)` facade.
-- This reconciliation is local only. Independent review, fresh exact-head CI,
- unresolved-thread checks, dependency order, and ordinary publication remain
- required before merge or release.
-## 2026-08-11 current workspace propagation into variation PR #4280
-
-- PR `#4280` remains on `feat/4144-variation-export-continuation`, based on
- `feat/4218-toolstrip-workspace`. Exact published child
- `3337945699966b63cb5cd8e52d7c3b194315e911` is merged first with exact newly
- published parent `efbca84095b617b4018732f7802c2da3f0525387` second by a
- normal merge; no rebase, retarget, force-push, or parent rewrite is used.
-- All implementation and test paths merge automatically. The child variation
- export, typed unavailable outcomes, bounded tables, linked selection, and
- all-trial arc behavior remain authoritative while inheriting the parent's
- current workspace, launch-monitor/D-plane ancestry, split kinetics, and Qt
- typing repairs. Only append-only handoffs and SPEC conflict textually; both
- histories remain below.
-- Focused pre-commit regression is green: all 56 focused Python variation tests
- pass, and all 10 tests in the three focused React variation suites pass.
-- Exact post-commit PR-delta gates against the new parent are also green:
- pinned Ruff 0.14.10 checks and formats all five changed Python files, pinned
- MyPy 1.13.0 accepts all four changed production files, and pinned Bandit
- 1.7.7 finds no issues in those four files. Docs governance, 500-LOC budget,
- changed-Python policy, minimum-test contract, changed-test assertions, diff
- hygiene, React type-check, React lint, and the production web build all pass.
- The manifest artifact/checker/test do not exist on either side of this
- pre-manifest stack, so that later release gate is structurally not applicable.
-- This candidate remains local pending independent review, ordinary
- publication, protected
- exact-head CI, unresolved-thread checks, and dependency order.
-## 2026-08-11 reviewed workspace parent propagation into variation PR #4280
-
-- Exact remote variation child
- `668ba96746f79f7a12e8092161bd610054197f58` normally merges exact reviewed
- workspace/toolstrip parent `ccd0e026c580c93038fdf5c59d5d452a85ba27a0`
- in child-first order. PR base, stack order, and both histories remain intact;
- no rebase, reset, retarget, force-push, or parent rewrite is used.
-- The variation/export feature remains unchanged while inheriting the current
- kinetics split, Ground/Tee parity contracts, protected Ruff normalization,
- and complete workspace/toolstrip behavior. The sole feature-code conflict
- was obsolete monolithic kinetics source and is resolved to the validated
- parent façade. Seven duplicate child automation edits fail protected Ruff
- 0.14.10 formatting and are normalized to the exact reviewed parent blobs;
- the automation commit remains reachable in the child-first history.
-- This reconciliation is local only. Independent review, fresh exact-head
- protected CI, unresolved-thread checks, dependency order, and ordinary
- publication remain required before merge or release.
-## 2026-08-11 current #4203 propagation into workspace PR #4279
-
-- Draft PR `#4279` retains branch `feat/4218-toolstrip-workspace` and base
- `feat/4181-launch-monitor-registry`. Exact published child
- `ccd0e026c580c93038fdf5c59d5d452a85ba27a0` is merged first with exact
- newly published parent `7abce9ad767fe8311da66a1e5998b892ea3ca9de`
- second by a normal merge; no rebase, retarget, force-push, or parent rewrite
- is used.
-- All implementation paths merge automatically. The child workspace,
- toolstrip, visibility, navigation, playback, and independent-plot behavior
- remain authoritative while inheriting the parent's split kinetics and four
- behavior-preserving Qt primitive-return boundaries. Only append-only
- handoffs and SPEC require textual reconciliation, and both histories remain
- below.
-- Focused pre-commit regression is green: all 142 exact PR-delta Python tests
- pass, and all 32 tests in the eight changed React suites pass. Exact
- post-commit PR-delta gates against the new parent are also green: pinned Ruff
- 0.14.10 checks and formats all 27 changed Python files, pinned MyPy 1.13.0
- accepts all 18 changed production files, and pinned Bandit 1.7.7 finds no
- medium/high issues in those 18 files. Docs governance, 500-LOC budget,
- changed-Python policy, minimum-test contract, changed-test assertions, diff
- hygiene, React type-check, React lint, and the production web build all pass.
- The manifest artifact/checker/test do not exist on either side of this
- pre-manifest stack, so that later release gate is structurally not applicable
- to this propagation.
-- This candidate remains local pending independent review, ordinary
- publication, protected
- exact-head CI, unresolved-thread checks, and dependency order.
-## 2026-08-11 remote automation reconciliation for workspace PR #4279
-
-- Exact local workspace head `0b22c401a26c31441a599d8d9b39de123706e7ea`
- ordinarily merges exact remote head
- `61fe2d556a5413e525d958612ccfd57e65b8d5a2`, preserving both histories and
- the existing PR base `feat/4181-launch-monitor-registry` without rebase,
- reset, retarget, force-push, or parent rewrite.
-- The remote commit is a broad formatting-only automation sweep. Fifteen of
- its 23 paths, including six pre-existing `.codex-worktrees` gitlinks, were
- already byte-identical in the current parent. Its seven unique formatting
- edits did not match protected Ruff 0.14.10 output and are normalized back to
- the pinned form. Its sole content conflict was obsolete pre-split kinetics
- code; the current `pendulum.sample(...)` façade implementation remains
- authoritative, preserving the parent split and runtime behavior.
-- Workspace/toolstrip, module visibility, navigation, playback, independent
- plots, physics, frames, units, schemas, and public contracts remain intact.
- This history-preserving local reconciliation still requires independent
- review, exact-head protected CI, unresolved-thread checks, and dependency
- gates before publication or merge.
-
-## 2026-08-11 hosted MyPy repair propagation into workspace PR #4279
-
-- Exact workspace child `7806a16f58e1c6999d32f0127a187fbb21f839a1`
- normally merges exact published parent
- `3796b49e40b677fbac4e05739f8be49f905df2cb`; PR base, stack order, and
- both histories remain unchanged.
-- The inherited production delta is limited to four static
- `numpy.ndarray` casts in the kinetics façade, series, and dynamics modules.
- Workspace/toolstrip behavior and runtime arrays, physics, units, frames,
- public identity, and UI behavior are unchanged.
-- This merge is local only. Fresh exact-head protected CI, required review,
- unresolved-thread checks, and dependency gates remain release blockers.
-
-## 2026-08-11 latest #4203 propagation into workspace PR #4279
-
-- Exact parent `0216a547aa79727091a2939b96e779e8ddbd7304` is normally merged into
- child `61b7f48b5aeb7d57246b4963da3df086e79cbe15` without changing PR base,
- stack order, or either history.
-- No feature-code conflict exists. The workspace/toolstrip, visibility,
- navigation, playback, and plot controls remain intact while the child
- inherits the parent's pinned formatting and identity-preserving kinetics
- size-budget repair.
-- This merge is local only. Fresh exact-head protected CI, review, unresolved
- threads, and dependency gates remain required before publication or merge.
-
-## 2026-08-11 #4203 append-only SPEC preservation repair
-
-The first independent audit of local reconciliation candidate `e20b4f630...`
-found four exact D-plane parent rows omitted from the append-only SPEC history:
-2026-08-10 versions 1.13.11, 1.13.9, 1.13.7, and 1.13.6. They are restored
-verbatim in the current documentation-only follow-up. Production code, tests,
-merge parents, PR base, and local quality evidence are unchanged. Independent
-re-review, ordinary publication, protected CI, and downstream propagation
-remain open.
-
-## 2026-08-11 #4203 current D-plane parent reconciliation
-
-- Draft PR #4203 now requires a normal merge of exact current base
- `f3363aa88868f6a5c7e9ccfc682a9eca014e86c1` after exact published child
- `217e36dc93d30f79826847f958fbcd10805e58ed`; its base remains
- `feat/4189-dplane` and no history is rewritten.
-- The parent changes nine files. Its sole textual conflict is an inherited
- kinetics formatting edit. The already reviewed split kinetics facade stays
- authoritative and uses the typed `DoublePendulumSwing` object directly;
- the parent's explanatory geometry comment is retained.
-- Exact CI-pinned MyPy 1.13 validation then exposed four remaining Qt stub
- boundaries in the child delta. Responsive-event handling, legend visibility,
- ball-setup event filtering, and status text now narrow their unchanged Qt
- return values to the declared primitive contracts.
-- Focused regression, full PR-delta quality gates, independent review, normal
- fast-forward publication, and fresh protected exact-head CI remain required.
-
-## 2026-08-11 #4203 exact-head format completion
-
-- Protected CI on exact published head
- `7d69a545ae555679f0318940e67c1786626d6794` failed only Ruff formatting.
- Reproducing the exact pinned 0.14.10 check found eleven noncompliant changed
- Python files: four inherited files plus seven altered by the automated
- pre-commit repair.
-- The pending repair applies pinned Ruff formatting to exactly those eleven
- files. AST equivalence and focused tests must pass before independent review
- and ordinary fast-forward publication; no simulation, contract, or UI
- behavior is intentionally changed.
-
-## 2026-08-11 #4203 hosted MyPy kinetics repair
-
-- Exact head `0216a547aa79727091a2939b96e779e8ddbd7304` failed CI Standard run
- `31477542889`, job `93734652129`, at runtime merge ref `aede309`: NumPy's
- typed API exposed four `no-any-return` findings in the newly extracted
- kinetics modules.
-- The repair narrows only the results of `numpy.linalg.norm`,
- `numpy.concatenate`, and the app-frame matrix projection to the already
- declared `numpy.ndarray` return contract. Explicit casts do not allocate,
- convert, or change any array, physics, units, frames, public identity, or UI.
-- RED evidence is the exact four hosted diagnostics at
- `_kinetics_series.py:121/131`, `_kinetics_dynamics.py:194`, and
- `kinetics.py:61`. GREEN evidence requires the complete PR-base changed-source
- MyPy profile, not a three-file-only run, plus focused/full Rate regression and
- normal protected CI after publication.
-- Local GREEN evidence is 102/102 complete-delta MyPy source files, 141/141
- Ruff/format files, 101 Bandit source files with no medium/high finding, 28/28
- focused tests, and 701/701 full Rate tests. Size, documentation, minimum-test,
- and diff gates also pass.
-- This commit is local only. PR base, stack order, protected review, and the
- paused #4279 parent propagation remain unchanged.
-
-## 2026-08-11 #4203 kinetics size-budget repair
-
-- Exact head `572bf525dd1ded26cbc3fbb4f228d1f6ca16e118` passes the PR-base
- changed-file scan because `kinetics.py` is byte-identical to the inherited
- parent, but the stricter `HEAD~1` scan selects the Ruff-formatted file and
- fails it at 646 LOC against the ungrandfathered 500-LOC limit.
-- The behavior-preserving LoD/DRY split leaves
- `simulation/kinetics.py` as the stable 222-LOC public façade, moves pure
- dynamics to `_kinetics_dynamics.py` (205 LOC), and moves the immutable
- series/DbC contract to `_kinetics_series.py` (131 LOC). Public constants,
- class/function objects, and the private `_reaction_forces` compatibility
- seam are identity-pinned by a RED-first contract test.
-- Physics, units, frames, numerical parity fixture, PyQt presentation, and
- release-stack order are unchanged. This implementation is committed locally
- only; no push, PR mutation, or release claim is authorized by this handoff.
-- Verification includes 28 focused kinetics/presentation/PyQt tests and the
- complete 701-test Rate-of-Closure Python suite, all passing locally.
-
-## 2026-08-11 #4203 pinned-Ruff formatting repair
-
-- No material handoff change: this commit only applies the repository-pinned
- Ruff 0.14.10 formatter to the eight Python files named by current-head CI
- Standard run `31468208320`, job `93705508050`.
-- Physics, application behavior, public contracts, schemas, UI layout, stack
- bases, and dependency order are unchanged. Fresh protected CI and review at
- the resulting head remain required; queued runner jobs are not green
- evidence.
-
-## 2026-08-10 #4143 child receives repaired #4203 parent
-
-- Ready PR `#4325` retains branch `feat/4143-tee-parity-fixture` and base
- `feat/4181-launch-monitor-registry`; repaired parent head
- `12dd76a8dbcc106c4683f2f2e53076f8dc6f1b76` is incorporated through a
- normal merge commit without rebasing, retargeting, or rewriting history.
-- The merge tree has no production/test-code conflict. Both branches'
- append-only handoff/SPEC evidence is retained, including the shared parity
- fixture and deterministic web/PyQt visual evidence.
-- Fresh exact-head protected CI and review remain required. #4143 stays open
- until the dependency line lands on `main`.
-
-## 2026-08-10 #4143 Python/React Golden Ball-Setup Parity
-
-- Branch `feat/4143-tee-parity-fixture` starts from exact draft PR #4203 head
- `31cbc007d4c85b5479b7cd0fb0969124eab2af67`; it does not rewrite or retarget
- the release stack.
-- `ball_setup_golden_v1.json` is the single Python/React source of truth for
- schema `rate_of_closure.ball_setup_golden` version 1, SI metre units, and
- reference `ground_plane_to_ball_bottom`. It pins Driver/Tee and iron/Ground
- defaults, explicit overrides, Ground's zero effective tee height, derived
- center geometry, serialization, negative and non-finite rejection, and
- legacy-run migration to Ground.
-- New consumer tests plus the existing tee suites pass: 18 Python tests and 24
- React tests. Web TypeScript, ESLint, and production Vite build gates pass;
- scoped Ruff check and format pass. This is test/fixture-only and does not
- change production physics or UI behavior.
-- Deterministic 1600 x 1200 Playwright captures cover the default Driver/Tee
- and rerun explicit-Ground React states with checked/disabled controls,
- present/absent tee geometry, and zero console/page errors. A hidden 1400 x
- 900 PyQt harness records the same states with canonical center and tee-artist
- assertions; a headless regression keeps its temporary PNGs nonblank and
- structurally distinct without pixel-perfect baselines. Artifact manifests
- and SHA-256 digests are under
- `C:\Users\diete\AppData\Local\Temp\rate-4143-visual-evidence-8050eeba`.
-- Issue #4143 remains open for exact-head protected CI/review and release to
- `main`. The strict campaign release manifest is not present on #4203's exact
- history (it was introduced later on a divergent campaign branch), so this
- bounded child records that limitation instead of reconstructing it.
-## 2026-08-10 Repaired wind-scalar parent propagation
-
-## 2026-08-10 PR #4282 exact-head mypy repair
-
-Protected quality-gate run `31395741841`, job `93478091420`, checked merge ref
-`ae75c4b006072b20a713e45b177defcc16a380fe` for exact head
-`aa6eeffb0395f7ed7954f2315b1c625cada552d8`. Checkout, dependency install,
-Ruff, and formatting passed; pinned mypy 1.13 then failed only
-`scripts/rate_campaign_manifest.py:335:5 [no-any-return]`. Under the exact CI
-`--follow-imports=skip` profile, Pydantic's `model_validate_json` return is
-`Any`. The validated local now carries an explicit `CampaignManifest` type,
-preserving runtime behavior without a redundant cast or suppression. Do not
-retry or cite the obsolete failed head as passing.
-
-## 2026-08-10 Exact workspace-parent propagation into PR #4280
-
-Draft PR `#4280` remains on `feat/4144-variation-export-continuation` with
-base `feat/4218-toolstrip-workspace`. The normal merge starts from original
-child head `f90836e342efc8be624739802375af2876d11e5f` and incorporates exact
-published parent head `6717e9e09d507dbc24bedb36177f1cdf0b4fd90b` as
-the second parent. No rebase, retarget, force-push, parent rewrite, or draft-
-state change is permitted.
-
-The source merge is conflict-free: the child's selected-scatter CSV export,
-typed unavailable values, accessible raw tables, linked selection, and focused
-PyQt/React visualization modules remain intact alongside the parent's complete
-workspace/toolstrip, playback, plot, navigation, Python 3.10, and module-budget
-repairs. SPEC 1.14.12 records this combined child release above the unique
-parent 1.14.11 entry. Staged review found and the continuation corrected one
-release-blocking rerun defect: replacing a study after selecting a later trial
-now clears linked selection atomically. Every PyQt public setter validates
-against the current trial count, while React clears on result identity change
-and shares only bounded selections, so a smaller rerun cannot crash or leave
-all new points dimmed.
-
-Verification is green: 37 focused variation GUI/export tests and the complete
-Rate/shared-swing/golf-club matrix passes 1,528 tests with two explicit
-optional build123d skips; all
-546 React tests pass across 90 files, as do TypeScript, ESLint, and the Vite
-production build. Exact-parent Ruff, Ruff-format, Black, pinned MyPy 1.13 for
-all four changed Python production modules, Bandit, the four-file 500-line gate,
-docs, minimum-test, changed-test assertions, detect-secrets fingerprints, and
-diff checks pass. CPython 3.10.20 compiles all changed Python files, and 30
-compatibility/date-boundary regressions pass. There is no Rust delta from the
-exact parent, whose 12-test `swing-core` evidence remains applicable.
-Independent staged re-review found no actionable findings after verifying the
-atomic result-identity boundary and validated-value widget updates. Protected
-exact-head CI and required repository review remain release gates after
-guarded publication.
-
-## 2026-08-10 Second workspace-parent propagation into PR #4280
-
-## 2026-08-10 Exact wind-adapter propagation into PR #4282
-
-Draft PR `#4282` remains on `feat/4199-wind-workflow` with base
-`feat/4199-wind-scalar-adapter`. The normal merge starts from original child
-`5f77af4add23547a21cc3fabce98ae9ad4260427` and incorporates exact published
-parent `4a793c4c3f19aad43a3c215800b266be487ace49` second. Do not rebase,
-retarget, force-push, rewrite either parent, change draft state, or merge the PR.
-
-The consolidated responsive wind/capability workflow and campaign release
-authority remain additive with the parent's variation visualizations,
-result-local selection, workspace/toolstrip, Python 3.10 compatibility, and
-matching `scalar-ensemble/v1` wind adapter. The canonical navigation-state
-module now owns the child capability-tab ID, preserving the parent's safe
-legacy visibility migration without duplicating navigation constants. The
-parent's strict deterministic wind boundary also remains intact: exact
-per-trial provenance, zero shear/turbulence, seed zero, and no gusts.
-Static review replaces child-owned optimized-away runtime assertions with
-explicit invariant failures and identifies the fixed-argument executable
-builder subprocess boundary with Bandit's native annotations. The exact-head
-CI repair above handles the separate skipped-import Pydantic return boundary.
-
-SPEC 1.14.14 is the unique combined child entry above parent 1.14.13.
-Verification is green across 73 focused Python navigation/wind/compatibility
-tests, the complete Rate/shared-swing/golf-club matrix (`1,657 passed`, two
-explicit optional build123d skips), and all 643 React tests across 105 files.
-TypeScript, zero-warning ESLint, Vite production build, 12 Rust tests, 31 real
-CPython 3.10 compatibility tests, and 43 post-review invariant/GUI/manifest
-tests pass. Ruff/format, pinned MyPy 1.13 across 37 changed production files,
-Bandit, the exact-parent 500-line budget, campaign-manifest contracts,
-docs/minimum-test/assertion governance, CI-policy secrets scan, compilation,
-and diff gates pass. Independent re-review found no actionable findings after
-94 Python workflow/navigation tests, 20 manifest/GUI tests, and 61 React
-workflow tests plus independent static checks. Protected current-head CI,
-unresolved threads, and required repository review remain release gates.
-
-## Active Rate of Closure campaign
-
-The active checkout is
-`C:\Users\diete\Repositories\Tools-worktrees\toolstrip-workspace` on the
-existing PR #4282 carrier `feat/4199-wind-workflow`. The local continuation
-starts from original published head
-`5f77af4add23547a21cc3fabce98ae9ad4260427` and normally incorporates exact
-published #4281 parent `4a793c4c3f19aad43a3c215800b266be487ace49`
-without changing the branch base `feat/4199-wind-scalar-adapter`. It composes
-four reviewed slices:
-strict capability parsing and signed decimal entry; complete capability
-diagnostics/result exports and quantitative React scatter scales; package-safe
-static-web release entrypoints; and the strict `rate-of-closure-campaign/v1`
-release-evidence authority. The normal merge also carries the parent's
-Python 3.10 compatibility, variation-export, and scalar-ensemble corrections.
-No branch was rebased, retargeted, rewritten, or force-pushed. Protected CI
-and review remain due after normal publication.
-
-Canonical files:
-
-- `docs/release/rate_of_closure_campaign.v1.json` — normalized campaign state;
-- `scripts/rate_campaign_manifest.py` — schema and contradiction validator;
-- `docs/release/RATE_OF_CLOSURE_CAMPAIGN_MANIFEST.md` — maintenance procedure;
-- `src/rate_of_closure/AGENT_HANDOFF.md` — current Rate-specific handoff;
-- `docs/development/RATE_OF_CLOSURE_CAMPAIGN_HANDOFF.md` — historical detail.
-
-The manifest deliberately reports the campaign as **not released**. It
-distinguishes specified scope, feature-stack implementation, protected parent
-merge, and exact `main` release. A local pass, a feature-branch merge, and a
-default-branch release are never interchangeable.
-
-## Current carrier and release state
-
-Capability PRs #4294, #4289, and #4283 were merged top-down into
-`feat/4199-wind-workflow`; their feature parents were not protected. PR #4282
-is the current open carrier on base `feat/4199-wind-scalar-adapter`. Exact
-published parent `4a793c4c3f19aad43a3c215800b266be487ace49` is incorporated
-through the normal local merge containing this handoff.
-
-The previous exact #4282 head `3186a265b1` built and loaded `swing_core`, but
-its Python 3.11 parity job failed before collection because a cached
-`pytest-qt` plugin loaded without PyQt6. Commit `18fe89201` disables third-party
-pytest plugin auto-loading only in that Rust parity step. Its focused workflow
-contract test passes; a fresh hosted parity run is still required.
-
-Combined local evidence on the composed continuation is 1,657 Python tests
-with two explicit optional skips and 105 React files / 643 tests, plus the
-TypeScript, zero-warning ESLint, 188-module Vite build, Rust, Python 3.10,
-manifest, Ruff, pinned mypy, Bandit, governance, secrets, compilation, and
-diff evidence recorded above.
-
-Hosted quality-gate run `31340032608` reached mypy 1.13 and exposed
-CI-context-only `no-any-return` findings in the Pydantic manifest loader and
-Qt elapsed-timer adapter because the delta lane uses `--follow-imports=skip`.
-Both boundaries now narrow their return values explicitly. The exact Python
-3.12/mypy 1.13 delta is clean across 54 files; Ruff passes and 62 focused
-regression tests plus eight campaign-manifest tests pass (only pre-existing
-optional-plugin config warnings).
-
-Corrected-parent propagation evidence is 62 focused wind/scalar/variation and
-compatibility tests on both Python 3.11 and real CPython 3.10.20, plus 8 React
-files / 35 tests, TypeScript, and focused zero-warning ESLint. The Python 3.10
-run exposed one child-owned direct `enum.StrEnum` import in capability
-observations; it now uses the shared runtime compatibility contract and is
-included in the source-level regression. Ruff check/format passes 15 focused
-files, pinned mypy 1.13 passes 10 production modules, and all nine campaign
-manifest/parity contracts pass.
-
-The direct web launcher dynamically loads the root bootstrap through
-`importlib` instead of mutating `sys.path` in the changed entrypoint. Its real
-child-process delegation test and the changed-Python policy guard cover that
-release path.
-
-Only `main` is the release boundary. It requires `quality-gate` and
-`tests (3.11)`. Outer PR #4119 remains the main-targeting platform carrier and
-requires current-main reconciliation. Impact-interval PR #4133 merged after
-its parent stack had already propagated and is not proven in #4119.
-
-## Critical open programs
-
-- #4142/#4144: variation graphics are substantial, but global sensitivity,
- bounded performance, downstream pinning, and release remain.
-- #4146: club-builder core exists; manufacturing export, image fitting, full
- client workflow, and downstream qualification remain.
-- #4158: wedge kinematics, clearance, turf, visualization, and forgiveness are
- feature-stack implementations without a protected release.
-- #4191/#4201: wind, inverse flight, playback, and capability work exist on the
- stack; scientific, installed-package, and cross-surface release gates remain.
-- #4218/#4234: toolstrip and selected layout fixes exist; camera issue #4284,
- complete persistence, high-DPI, keyboard, and visual baselines remain.
-- #4260/#4267: four-surface parity is specified; ground contracts/transfer are
- partial and bounce, skid, roll, total distance, UI, and parity remain open.
-
-## Required validation
-
-```powershell
-python scripts/rate_campaign_manifest.py
-python -m pytest tests/rate_of_closure/test_campaign_release_manifest.py -q
-python -m pytest tests/ops/test_maturin_swing_core_workflow.py -q
-python -m ruff check scripts/rate_campaign_manifest.py `
- tests/rate_of_closure/test_campaign_release_manifest.py
-python -m ruff format --check scripts/rate_campaign_manifest.py `
- tests/rate_of_closure/test_campaign_release_manifest.py
-python -m mypy --ignore-missing-imports scripts/rate_campaign_manifest.py
-```
-
-For a feature change, also run the complete affected Rate Python/PyQt/shared
-swing and React suites recorded in the per-tool handoff.
-
-## Do not
-
-- Do not mark a program released without a 40-character `main` merge SHA.
-- Do not convert queued, cancelled, skipped, or failed checks into passing
- evidence.
-- Do not retarget or rewrite the protected stack, force-push, or admin-merge.
-- Do not duplicate carrier or test metadata in individual program records.
-- Do not treat an UpstreamDrift launcher tile as four-surface parity.
-
-Fleet handoff policy is tracked by Repository_Management #1393/#1397. Any
-`src/**` handoff change also requires the same-commit `SPEC.md` update.
-
-## 2026-08-10 Final repaired #4282 propagation into PR #4285
-
-Draft PR `#4285` retains branch `feat/4268-ground-contract` and base
-`feat/4197-capability-observer`. Original child head
-`e5bcbd1096d3be1f621a805c9d9f3fd321e375a5` now normally incorporates exact
-quality-green workflow head `1e82f15026786ea0b08f78f4c001590ddce9ff39`
-second. No ground-contract production or test code conflicted, and no rebase,
-retarget, force-push, parent rewrite, or draft-state change was used. Fresh
-protected CI/review is required before downstream #4288 propagation.
-
-## 2026-08-10 Final repaired ground-contract propagation into PR #4288
-
-Draft PR `#4288` retains branch `feat/4269-flight-ground-transfer` and base
-`feat/4268-ground-contract`. Original child head
-`108a841b1378c992defd3c7b7ee263d41a6c8b24` normally incorporates exact
-quality-green parent `a93edb4bfd6a8dc9334122cd2ae660983d5bf424`
-second. No transfer production or test code conflicted. No rebase, retarget,
-force-push, parent rewrite, or draft-state change was used; fresh protected CI
-and review remain required.
-
-## PR #4288 exact repaired-ground propagation
-
-Draft PR #4288 remains on `feat/4269-flight-ground-transfer` with unchanged
-base `feat/4268-ground-contract`. Original child
-`247215422a6d4b677552955b4923bc609a553259` normally incorporates exact repaired
-#4285 parent `e5bcbd1096d3be1f621a805c9d9f3fd321e375a5` second in the
-merge containing this handoff. The child preserves its signed terminal state,
-physical sphere/terrain contact brackets, strict provenance, and qualified
-Python/TypeScript/Rust/PyO3/WASM transfer while inheriting deterministic
-workspace timestamps, canonical `swing_sim` import identity, the hosted-mypy
-manifest repair, and the complete variation, wind, capability, and campaign
-ancestry. No branch was rebased, retargeted, rewritten, or force-pushed.
-
-This propagation adds no bounce, skid, roll, terrain response, total distance,
-or UI execution. Protected CI, independent review, and dependency-ordered
-collapse remain separate release gates.
-
-Exact composed-tree verification is 1,080 Python tests passed with six explicit
-optional installed-`tools_core` wheel skips, 107 React files / 662 tests,
-26 direct Rust transfer/wire tests, TypeScript, zero-warning ESLint, and the
-189-module production build. Ruff check/format passes all 28 changed Python
-files; pinned mypy 1.13 passes all 21 changed production files. Campaign
-manifest validation, documentation governance, and diff checks are clean. The
-missing local wheel is not accelerated installed-package evidence and remains
-an explicit release boundary; the direct Rust suites executed rather than
-being relabeled as wheel parity.
-
-## 2026-08-10 Exact repaired #4282 propagation into PR #4285
-
-Draft PR #4285 remains on `feat/4268-ground-contract` with unchanged base
-`feat/4197-capability-observer`. The normal merge containing this handoff keeps
-original child `788aa547651a3685a363ea401824a5d81477bafb` first and incorporates
-exact repaired #4282 carrier `686016196a2f895058b8a566dff103a0fd32cd10`
-second. That carrier contains merged capability PR #4283 commit
-`c1827bbdc50a6e11cc475db2636b4e47a4c15416`, exact observer head
-`9bbb98e16e435a0d4c74153b909f2ebfefbbce7a`, and the hosted-mypy manifest
-repair following predecessor `aa6eeffb0395f7ed7954f2315b1c625cada552d8`.
-No branch was rebased, retargeted, rewritten, or force-pushed.
## 2026-08-09 PR #4304 corrected implementation evidence
@@ -1391,54 +625,6 @@ UI, TypeScript/Rust/PyO3/WASM physics, and downstream parity remain open.
Protected CI, independent review, exact-head publication, parent integration,
and consumer delivery are still required.
-## 2026-08-10 Exact repaired #4282 propagation into PR #4285 (continued)
-
-The inherited ground descendant passes 1,703 Python tests with two explicit optional
-`build123d` skips, 643 React tests across 105 files plus type-check,
-zero-warning lint and production build, 12 Rust tests, and 77 ground plus
-compatibility tests on real CPython 3.10. Ruff/format cover 78 changed Python
-files; pinned mypy and Bandit cover 52 changed production files. Campaign
-manifest, documentation, minimum-test, changed-assertion, 500-LOC, changed-file
-secrets, Python 3.10 compilation, and diff gates are clean. Protected
-current-head CI and required review remain separate release gates. Its exact
-repaired head is now incorporated into #4288; normal propagation of the
-reviewed #4288 head into #4298 is the next ancestry gate.
-
-The composed pinned-mypy profile additionally exposed integration-only `Any`
-returns at the Pydantic manifest and scalar plotting boundaries. The repaired
-#4282 parent owns the manifest annotation; scalar extraction normalizes the
-already-validated value with `float`. Bandit also replaced an optimized-away
-command-state assertion with an explicit invariant error. The alias finder
-retains its intentional optional-probe catch-and-continue boundary under a
-narrow explanatory `B112` annotation.
-
-## 2026-08-09 Ground parent reconciled with corrected wind carrier
-
-Draft PR #4285 remains on `feat/4268-ground-contract` with unchanged base
-`feat/4197-capability-observer`. Exact corrected wind carrier
-`bb101cedd555d07d493aae998b46050c68660cdd` is incorporated by the normal
-local merge containing this handoff; no branch was rebased, retargeted,
-force-pushed, or published. The result is the carrier-reconciled ground parent:
-it retains the strict flight-to-ground schemas, canonical fixtures, migrations,
-legacy-result adapter, dependency declaration, and pinned-mypy repairs while
-carrying the complete corrected wind/scalar/variation/Python-3.10 and
-consolidated capability ancestry.
-
-No qualified bounce, skid, roll, terrain-profile, total-distance, UI, or
-Rust/WASM ground physics is added by this propagation. PR #4288 must normally
-merge the resulting exact #4285 head before its flight-to-ground transfer can
-be evaluated as a descendant of the corrected carrier. Because #4285 still
-targets the observer branch while the corrected carrier now contains that
-observer through wind workflow #4282, this merge is the explicit
-observer-to-wind ancestry reconciliation; the GitHub base remains unchanged.
-
-Focused evidence is 89 ground-contract, compatibility, scalar-adapter, and
-responsive-wind tests on Python 3.11 and the same 89 on real CPython 3.10.20.
-Ruff check/format passes 34 focused Python files; pinned mypy 1.13 passes 23
-production modules. Ground production modules remain below 400 lines and
-functions below 50 lines, with no placeholder markers. The inherited campaign
-manifest validates and its nine manifest/parity contracts pass.
-
## 2026-08-09 PR #4302 pinned-MyPy current-head correction
Hosted quality-gate run `31350134551` exposed four deterministic MyPy 1.13
@@ -1740,6 +926,7 @@ npm run type-check
npm run lint
npm run build
```
+
## 2026-08-09 PR #4302 deterministic-digest scanner repair
Protected CI correctly remained blocking at head
@@ -1753,567 +940,3 @@ Commit this narrow repair with all three canonical handoffs and push normally
to `feat/4270-ground-impact-bounce`. Do not retry the unchanged failed run,
amend history, or force-push. Descendant PRs #4304 and #4305 inherit this file
and must later receive the parent by ordinary merge commits.
-## 2026-08-11 parent handoff sections preserved during #4282 reconciliation
-
-## 2026-08-10 Second variation-parent propagation into PR #4281
-
-- Draft PR `#4281` retains branch `feat/4199-wind-scalar-adapter` and base
- `feat/4144-variation-export-continuation`. Exact repaired parent head
- `b90e5021a59e2081415b51ef29fbed06377bc201` is incorporated through a
- normal merge commit without rebase, retarget, force-push, or history rewrite.
-- There is no scalar-adapter production/test conflict. Both append-only
- handoff/SPEC histories are retained and the adapter contract is unchanged.
-- Parent quality success is not child release evidence. Fresh exact-head CI,
- review, and all earlier dependencies remain open.
-- Reconciled-child evidence is 25 focused D-plane/impact tests plus docs
- governance, changed-file size budget, and whitespace checks.
-
-## 2026-08-10 Parent Repair Propagation (#4202 → #4203)
-
-- Draft child PR `#4203` remains on `feat/4181-launch-monitor-registry`, based
- on `feat/4189-dplane`; neither branch nor PR base is rewritten.
-- Original child head `08a2fdd8ce6bbc8fbb8f121927a677d4addb6b11` is
- normally merged with exact parent head
- `b443fdbed7064c5db0320106013c8413e3e24356`, in that parent order.
-- The semantic reconciliation preserves #4203's responsive
- `SimulationViewControlsMixin` architecture while delegating persisted
- D-plane checkbox state to the parent's focused `ImpactLayerControls`
- helper. The existing `_impact_layer_checks` automation seam aliases the
- helper's single checkbox mapping, so no duplicate UI state is introduced.
-- The inherited Python 3.10 compatibility repairs, frame-explicit D-plane
- geometry, launch-monitor registry, responsive layout, and exports remain
- additive. `simulation_view.py` and its controls mixin both remain below the
- protected 500-line limit.
-- The exact original child also carried three ungrandfathered module-budget
- blockers before this propagation: `simulation/sources.py` (540 LOC),
- `plotting/catalog.py` (533 LOC), and `ui/pyqt6/main_window.py` (528 LOC).
- Behavior-preserving extractions now isolate triple-pendulum dynamics,
- plotting metadata, and versioned primary-navigation persistence. The legacy
- source, catalog, and main-window imports are identity-preserving re-exports;
- the split modules are 282/282, 459/98, and 494/85 lines respectively.
-- Focused reconciliation and extraction evidence is green: 36 PyQt
- simulation/layout tests, 38 plotting/navigation tests, and 21 simulation
- source/export tests. Final combined-stack evidence is 1,249 passing Python
- tests with six explicit optional-dependency/Rust-wheel skips; 521 passing
- React tests plus TypeScript, ESLint, and Vite production gates; 12
- `swing-core` tests; real CPython 3.10 compilation/import checks; scoped
- Ruff/Black/pinned MyPy; docs, minimum-test, assertion, changed-file size,
- detect-secrets, and diff gates. A full-tree audit separately retains two
- untouched non-candidate size findings (`kinetics.py`, 646 LOC;
- `torque_profile_panel.py`, 612 LOC). Independent staged review found no
- actionable findings after 95 additional focused tests. Exact-head protected
- CI and required repository review remain release gates.
-
-## 2026-08-09 PR #4203 Python 3.10 string-enum compatibility
-
-Current-head child CI exposed a collection boundary that was already present
-in PR #4203's parent surface: seven Rate/shared swing modules imported
-`enum.StrEnum`, which does not exist on Python 3.10. Runtime imports now use
-the repository's existing `shared.python.compatibility.StrEnum`; type checking
-retains the native stdlib symbol behind `TYPE_CHECKING` so pinned mypy 1.13
-keeps enum-member types rather than weakening them to strings. No enum values,
-serialized contracts, physics, or UI behavior changed.
-
-This repair is published at exact #4203 head
-`ab7de5a47977417e02926c3fbc7476002e82b690`. Evidence:
-64 focused convention, D-plane, manual-delivery, flight-result, inverse,
-impact-family, capability, and compatibility tests pass; Ruff and format pass;
-pinned mypy 1.13 passes all eight changed Python files; and a real CPython
-3.10.20 probe verifies the shared fallback and all seven runtime import paths.
-Propagate the new parent normally through #4279, #4280, #4281, and #4282.
-
-The subsequent full Rate scan also found one parent-owned direct
-`datetime.UTC` import in the torque-profile controller. It now uses the same
-shared Python 3.10 compatibility module. The focused torque-profile UI suite
-and the real-3.10 source/runtime probe are required before publishing this
-follow-up; serialized timestamps remain UTC and the workspace schema is
-unchanged.
-
-## 2026-08-09 PR #4203 Linux collection repair
-
-Draft PR #4203 remains on `feat/4181-launch-monitor-registry`, based on
-`feat/4189-dplane`; no branch was rebased, retargeted, force-pushed, or merged
-on GitHub. Exact-head CI run `31199764932` passed the quality gate but all
-three Python lanes failed while collecting the in-package flight and solver
-facade contract tests. Pytest loaded those tests through its `src.shared...`
-package namespace, while their absolute dotted aliases requested the editable
-`shared...` namespace; Python then reported that `flight`/`solver` could not be
-imported from `src.shared.python.swing_sim` before any assertion ran.
-
-The bounded repair uses package-relative facade imports in those two tests, so
-collection and the public API assertions stay in one namespace. It does not
-change production code or widen either facade. Verify both contract modules
-with `--import-mode=importlib`, Ruff/format, and pinned mypy before a normal
-push. The run's Rust `-lpython3.11` link error is missing runner toolchain
-state, not simulation evidence; do not modify the model to hide it. After the
-new #4203 head passes, propagate it through #4279, #4280, #4281, and #4282 in
-normal stack order.
-
-Local evidence is now `12 passed` on Windows and `12 passed` under WSL Python
-3.11 with importlib collection. Ruff check/format and pinned mypy 1.13 pass
-for both changed test modules. The frozen-dataclass assertion casts only its
-introspection target to `Any`, matching the later carrier boundary while
-retaining the runtime assertion. The minimal WSL environment reports only
-unknown-option warnings for intentionally omitted optional pytest plugins.
-
-## 2026-08-10 PR #4202 D-plane ndarray typing repair
-
-- Draft PR `#4202` remains on `feat/4189-dplane`, based on
- `feat/4162-wedge-impact-visualization`; the verified published repair base is
- `b443fdbed7064c5db0320106013c8413e3e24356`.
-- CI Standard run `31384810375`, job `93442745760`, exposed two exact pinned
- MyPy 1.13 `no-any-return` findings in the private D-plane ndarray helpers.
- Explicit local ndarray result boundaries now preserve those helpers' return
- contracts without changing validation, arithmetic, frames, schemas, or any
- public API.
-- TDD evidence: the exact two-error MyPy failure was reproduced before the
- repair; the same command is green afterward. Twenty-four focused D-plane,
- impact-contract, impact-kinematics, and impact-scene tests pass, together
- with seven metadata/pre-push contract tests, scoped Ruff, Ruff format, Black,
- docs governance, minimum-test, module-size, changed-file-size, and diff
- checks. An exploratory CI-workflow contract slice retains three unrelated
- failures for later toolcache/environment steps absent from this older branch;
- no workflow file is changed by this repair.
-- This is a bounded quality-gate repair, not completion of D-plane issue
- `#4189`. Protected current-head CI, dependency order, and required review
- remain release gates; no push, retarget, or draft-state change is included.
-
-## 2026-08-10 Parent Repair Propagation (#4179 → #4202)
-
-- Child PR `#4202` remains on `feat/4189-dplane`, based on
- `feat/4162-wedge-impact-visualization`; neither branch nor PR base is
- rewritten.
-- Original child head `b4abec03bccfbdd87ddf91427159c5c2332c21dd` is
- normally merged with exact parent head
- `6704a3e541a3e74c28b4a284530d1a21269dd340`, in that parent order.
-- The Python 3.10 UTC repair and source-wide AST guard remain additive to the
- frame-explicit 3D D-plane geometry, desktop/web overlays, and export
- contracts.
-- The persisted D-plane layer controls are extracted into a focused helper,
- restoring `simulation_view.py` to the protected 500-line module budget
- without changing its compatibility seam or behavior.
-- Combined-stack verification is green: 93 focused and 825 scoped Python tests
- with two optional `build123d` skips; 360 React tests plus TypeScript, ESLint,
- and Vite production gates; real CPython 3.10.20 compilation/UTC; Ruff/Black;
- focused pinned MyPy 1.13; docs, minimum-test, file-size, detect-secrets, and
- diff checks. The exact parent's 12 unchanged `swing-core` tests remain
- applicable because this child has no Rust delta. The inherited broad MyPy
- baseline remains 17 Qt/NumPy typing findings in 11 untouched files.
- Protected CI and required review remain release gates.
-
-## 2026-08-10 Parent Repair Propagation (#4178 → #4179)
-
-- Child PR `#4179` remains on `feat/4162-wedge-impact-visualization`, based on
- `feat/4166-wedge-turf-physics`; neither branch nor PR base is rewritten.
-- Original child head `0eb804e70887c788421332369e42792411aff55a` is
- normally merged with exact parent head
- `bfa83aedc88ead380babc73a699377d98b971006`, in that parent order.
-- The Python 3.10 UTC repair and source-wide AST guard remain additive to the
- exact-event, locked-scale wedge impact visualization contracts.
-- Combined-stack verification is green: 58 focused and 739 scoped Python tests
- with two optional `build123d` skips; 347 React tests plus TypeScript, ESLint,
- and Vite production gates; real CPython 3.10.20 compilation/UTC; Ruff/Black;
- focused pinned MyPy 1.13; docs, minimum-test, file-size, detect-secrets, and
- diff checks. The exact parent's 12 unchanged `swing-core` tests remain
- applicable because this child has no Rust delta. The inherited broad MyPy
- baseline remains 17 Qt/NumPy typing findings in 11 untouched files.
- Protected CI and required review remain release gates.
-
-## 2026-08-10 Parent Repair Propagation (#4174 → #4178)
-
-- Child PR `#4178` remains on `feat/4166-wedge-turf-physics`, based on
- `feat/4161-wedge-ground-clearance`; neither branch nor PR base is rewritten.
-- Original child head `aaae3f73e17dbfaad5cca1dc6f49559b3aebe9d5` is
- normally merged with exact parent head
- `9ea93e92563280ec34bca682ad44d7409edd7a02`, in that parent order.
-- The Python 3.10 UTC repair and AST guard remain additive to the validated
- turf-contact contracts and their explicit scientific/calibration boundary.
-- Combined-stack verification is green: 56 focused and 732 scoped Python tests
- with two optional `build123d` skips; real CPython 3.10.20 compilation/UTC;
- Ruff/Black; focused pinned MyPy 1.13; docs, minimum-test, file-size,
- detect-secrets, and diff checks. With no TypeScript or Rust delta, the exact
- parent evidence of 345 React tests/all web gates and 12 `swing-core` tests is
- unchanged. The inherited broad MyPy baseline remains 17 Qt/NumPy typing
- findings in 11 untouched files. Protected CI and review remain release gates.
-
-## 2026-08-10 Parent Repair Propagation (#4173 → #4174)
-
-- Child PR `#4174` remains on `feat/4161-wedge-ground-clearance`, based on
- `feat/4163-impact-inspector`; neither branch nor PR base is rewritten.
-- Original child head `880a6465fc872cf3d6650283db154ddc41793a31` is
- normally merged with exact parent head
- `9ddaff3b6bca542fd7a2befc7d7b0ae53910a60a`, in that parent order.
-- The inherited Python 3.10 UTC repair and source-wide AST guard remain
- additive to the swept wedge ground-clearance contracts.
-- Combined-stack verification is green: 56 focused Python tests; 703 scoped
- Python tests with two optional `build123d` skips; 345 React tests plus
- TypeScript, ESLint, and Vite production gates; 12 `swing-core` tests; real
- CPython 3.10.20 compilation and UTC checks; Ruff/Black; focused pinned MyPy
- 1.13; docs, minimum-test, file-size, detect-secrets, and diff checks. The
- inherited broad MyPy baseline is 17 Qt/NumPy typing findings in 11 untouched
- files and remains outside this propagation scope. Protected CI and review
- remain release gates.
-
-## 2026-08-10 Parent Repair Propagation (#4167 → #4173)
-
-- Child PR `#4173` remains on `feat/4163-impact-inspector`, based on
- `feat/4144-variation-visualizations`; neither branch nor PR base is rewritten.
-- The original child head `3c43955aaeb3964ff8c3ef2748d626baae518b76`
- is being merged normally with exact parent head
- `22b66b560652b78de84141344c4ddd9a92a83b26`, in that parent order.
-- The inherited repair replaces Python 3.11-only `datetime.UTC` use in Rate
- torque-profile persistence with `shared.python.compatibility.UTC` and adds a
- Rate-source AST regression guard for direct, aliased, and module-attribute
- access.
-- Combined local verification is green: 63 focused Python tests, all 562 Rate
- tests, all 334 React tests, TypeScript type-check, ESLint, Vite production
- build, 12 `swing-core` Rust tests, real CPython 3.10.20 compile/UTC checks,
- Ruff check/format, Black, focused pinned MyPy 1.13, docs governance,
- minimum-test, file-size, detect-secrets, and diff checks. A broader MyPy
- sweep still reports 17 pre-existing Qt/NumPy typing errors in 11 untouched
- files. Protected CI and required review remain release gates; queued,
- cancelled, missing-toolcache, and dependency-download jobs are not green
- evidence.
-- Every implementation commit must update this file, the Rate handoff, the
- campaign handoff, and `SPEC.md`, or explicitly record why there is no
- material handoff change.
-
-## Where This Repo Is Headed
-
-Tools is the D-sorganization fleet's shared engineering-tools monorepo (45+
-tools: PyQt6 GUIs, FastAPI/React web mirrors, Rust kernels). The current
-center of gravity is `src/rate_of_closure`, being grown from a single
-closure-rate calculator into a full swing → impact → ball-flight simulation
-platform under **Repository_Management#1390** (this handoff rollout) and a
-stack of golf-simulation epics:
-
-| Epic | Status (one line) |
-| ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| #4103 — Swing–Impact–Ball-Flight Simulation Platform | Phases 0-6 implemented on branch `feat/impact-simulation-platform`, consolidated into PR **#4119** (open, auto-merge armed, awaiting review). Phase 7 (WASM web parity swap, Pages CI) still open. |
-| #4120 — Investigation & Variation Suite (plotting/viewers/Monte Carlo/help) | V1-V4 implemented, stacked on #4119, consolidated into PR **#4124** (open, draft-for-review, no auto-merge yet — targets `feat/investigation-suite`, itself stacked on #4119). |
-| #4125 — Realistic Clubs/Kinetics/Putting/Public Release Mgmt/Showcase Styling | H1-H7 implemented, stacked on #4124, consolidated into PR **#4129** (open, draft-for-review, targets `feat/course-showcase`, stacked on #4124). H5 (public release-management repo) is cross-repo, not yet started. |
-| #4130 — Impact-Interval Club Dynamics (contact-interval rigid-body model) | Foundation epic only (F1 formulation doc not yet started); no PR yet. Next major physics wave after #4125 lands. |
-
-The separate shared Club Builder epic #4146 is active. Its first dependency
-slice, #4147, lives on `feat/4147-club-builder-core` and establishes the
-UI-independent assembly mass/CG/inertia, frame, length-datum, and persistence
-contracts that the later shaft, CAD, export, fitting, and UI issues consume.
-
-Active infrastructure repair: #4155 hardens the Rust/PyO3 job against
-incomplete setup-python cache entries whose interpreter works but whose
-declared link library is missing. The repair is isolated on
-`fix/4155-rust-libpython-cache` and does not change simulation code.
-
-See `src/rate_of_closure/AGENT_HANDOFF.md` for the detailed stack breakdown
-and architecture pointers for this tool specifically.
-
-## Must-Read Architecture Pointers
-
-1. `CLAUDE.md` — repo-wide conventions, CI gate list, cross-repo dependency
- rules (Tools is a leaf dependency; UpstreamDrift and Gasification_Model
- consume it).
-2. `docs/architecture/CANONICAL_TOPOLOGY.md` — canonical repo topology policy.
-3. `SPEC.md` — living specification; §12 Change Log requires a dated row for
- every PR touching `src/` (enforced by `spec-check.yml`, see gates below).
-4. `src/rate_of_closure/AGENT_HANDOFF.md`, `src/pendulum_simulator/AGENT_HANDOFF.md`,
- `src/rotation_converter/AGENT_HANDOFF.md` — per-tool handoff docs.
-5. `docs/AGENT_HANDOFF_TEMPLATE.md` — template for adding a handoff doc to a
- new tool.
-
-## In-Flight Branches (what stacks on what)
-
-```
-main
- └─ feat/impact-simulation-platform (PR #4119, epic #4103, auto-merge armed)
- └─ feat/investigation-suite (PR #4124, epic #4120, stacked on #4119)
- └─ feat/course-showcase (PR #4129, epic #4125, stacked on #4124)
-docs/agent-handoff-1390 (this branch, off origin/main, Repository_Management#1390)
-```
-
-Other active non-golf branches worth knowing about: `fix/file-size-budget-bounded-checkout`
-(#4096, CI checkout-scope fix), `agent/scada-phase-a-foundation` (#4091, SCADA
-epic #4085), several `scada/pr*` branches (SCADA epics #4085-#4089), and a
-handful of Bolt/Palette/Sentinel micro-PRs (#4070-#4102) unrelated to the
-golf-sim stack.
-
-## Gate Commands (repo-wide)
-
-```bash
-python3 -m ruff check . # lint
-python3 -m ruff format --check . # format check
-python3 -m pytest -n auto --timeout=60 # full test suite
-python3 -m pytest -m contract # API contract tests (downstream-facing)
-python3 -m pytest -m integration --timeout=60 # cross-repo integration
-```
-
-SPEC freshness (CI job `spec-freshness` in `.github/workflows/spec-check.yml`):
-any PR touching `src/**`, `tests/**`, `config/**`, `pyproject.toml`,
-`Cargo.toml`, `package.json`, or `requirements.txt` must also modify
-`SPEC.md` in the same PR, or carry the `spec-exempt` label. Runs on the
-`d-sorg-fleet` self-hosted runner.
-
-## Do-Not List
-
-- Do not modify public function signatures in `src/shared/python/**` without
- opening coordinated migration issues in UpstreamDrift and Gasification_Model
- (see `CLAUDE.md` Cross-Repo Dependencies).
-- Do not import across package boundaries (e.g. `signal_processing_studio`
- importing from `sidekick.process_calculators`) — LoD is enforced.
-- Do not exceed the 500-LOC file budget on new/modified files in the golf-sim
- packages (`rate_of_closure`, `swing_sim`, `swing-core`) — sub-package,
- don't grow monoliths.
-- Do not use `git commit --no-verify` / `--push --no-verify` to bypass hooks;
- see `CLAUDE.md` Hook bypass policy.
-- Do not regenerate the sidekick API baseline (`tests/sidekick_api_baseline.json`)
- without coordinating a breaking-change migration.
-- Do not merge #4124 or #4129 ahead of their base (#4119, #4124 respectively)
- — they are stacked and will conflict/duplicate SPEC.md sections if merged
- out of order.
-- Do not hand-roll a GitHub Pages deploy workflow for `rate_of_closure/web`
- yet — Phase 7 of #4103 owns this; today Pages hosting elsewhere in the repo
- (e.g. `unit_converter`) is done via manual branch-folder publish, not CI.
-
-## Short-Term Roadmap (ordered)
-
-1. Land PR #4119 (base platform) — currently the long pole; everything else
- stacks on it.
-2. Get #4124 out of draft-for-review and merge into `feat/investigation-suite`
- → cascades onto #4119.
-3. Get #4129 out of draft-for-review and merge into `feat/course-showcase`
- → cascades onto #4124.
-4. Start #4130 Phase F1 (formulation document) once #4125's stack is in.
-5. Phase 7 of #4103: WASM swap for the web mirror + real Pages CI deploy for
- `rate_of_closure/web`.
-6. #4125 H5: stand up the public release-management repo (cross-repo, not
- started).
-
-## 2026-08-11 additional parent sections preserved during #4282 reconciliation
-
-## 2026-08-10 Exact variation-parent propagation into PR #4281
-
-Draft PR `#4281` remains on `feat/4199-wind-scalar-adapter` with base
-`feat/4144-variation-export-continuation`. The normal merge starts from
-original child `cf52529b1e68479321bb93b1be3d59c77f782008` and incorporates exact
-published parent `8bcc49fc4e16e5e43be0b7f0f03c3017d5b79d0c` as its second parent. Do
-not rebase, retarget, force-push, rewrite either parent, or change draft state.
-
-The child's matching Python/TypeScript `scalar-ensemble/v1` contract and wind
-strategy plot adapter remain additive with the parent's selected-scatter
-exports, accessible raw tables, result-local linked selection, complete
-workspace/toolstrip, playback, navigation, compatibility, and module-budget
-repairs. Both adapters now enforce the same deterministic wind-scenario
-boundary: exact per-trial provenance, zero shear and turbulence, seed zero, and
-no gusts. SPEC 1.14.13 is the unique combined child entry above parent 1.14.12.
-
-Verification is green across 27 focused Python contract/adapter/selection
-tests, the complete Rate/shared-swing/golf-club matrix (`1,549 passed`, two
-explicit optional build123d skips), and all 556 React tests across 92 files.
-TypeScript, zero-warning ESLint, Vite production build, Ruff, Ruff-format,
-pinned MyPy 1.13, Bandit, the exact-parent two-file 500-line budget, docs,
-minimum-test, assertions, detect-secrets, diff, and CPython 3.10 compilation
-pass. Independent re-review found no actionable findings after checking the
-exact provenance derivation and all five deterministic-scenario regressions;
-protected current-head CI, unresolved threads, and required repository review
-remain release gates.
-
-## 2026-08-10 PR #4280 workspace timestamp propagation
-
-Draft PR #4280 remains on `feat/4144-variation-export-continuation` with base
-`feat/4218-toolstrip-workspace`. Exact corrected parent
-`05383d333b6fd87eaf5e37305476f50b505c2c2e` is incorporated through the normal
-merge containing this handoff, without rebasing, retargeting, force-pushing,
-or rewriting either branch. The child retains its selected-scatter CSV export,
-typed unavailable values, accessible raw tables, and focused visualization
-modules while inheriting the deterministic Python 3.10-3.12 UTC parser.
-
-The monotonic specification assigns the parent repair version 1.14.10 and the
-variation child version 1.14.11. The reconciled tree passes all `778` Rate
-tests, the real-CPython-3.10.20 compatibility suite (`27 passed`), the focused
-React variation suite (`1 file / 8 tests`), TypeScript, zero-warning focused
-ESLint, Ruff, format, and pinned mypy 1.13. Documentation, size, and diff gates
-must remain clean in the merge commit. Protected CI, review, and propagation
-to #4281 and later descendants remain separate release gates.
-
-## 2026-08-10 Second parent propagation into PR #4279
-
-- Draft PR `#4279` retains branch `feat/4218-toolstrip-workspace` and base
- `feat/4181-launch-monitor-registry`; exact repaired parent head
- `12dd76a8dbcc106c4683f2f2e53076f8dc6f1b76` is incorporated through a
- normal merge commit with no rebase, retarget, or history rewrite.
-- The trees have no feature-code conflict. Reconciliation retains both
- branches' append-only handoff/SPEC evidence, while the inherited D-plane
- ndarray typing repair remains numerically and behaviorally neutral.
-- Parent quality-gate success does not authorize this child. Fresh exact-head
- protected CI, review, and all dependency gates remain open.
-- Reconciled-child evidence is 25 focused D-plane/impact tests plus docs
- governance, changed-file size budget, and whitespace checks.
-
-## 2026-08-10 Exact parent propagation into PR #4279
-
-Draft PR `#4279` remains on `feat/4218-toolstrip-workspace` with base
-`feat/4181-launch-monitor-registry`. This merge starts from original child
-head `05383d333b6fd87eaf5e37305476f50b505c2c2e` and incorporates exact
-published parent head `31cbc007d4c85b5479b7cd0fb0969124eab2af67` through a
-normal two-parent merge; no rebase, retarget, force-push, or draft-state change
-is permitted.
-
-The semantic reconciliation preserves the child's File/View/Tools workspace,
-module visibility, granular playback, trail, plot, and launcher integration.
-It also keeps the parent's focused `ImpactLayerControls`, plotting catalog,
-triple-pendulum, and primary-navigation modules. Workspace navigation now
-aliases the parent's canonical stable-ID/settings constants, while retaining
-the child's visibility and required-module state. Impact-layer automation and
-the rendered controls share the parent's single checkbox mapping.
-
-Combined verification is green: 1,339 Python tests pass with six explicit
-optional build123d/Rust-wheel skips; 545 React tests pass across 89 files, and
-TypeScript, ESLint, and the Vite production build pass. The post-format semantic
-rerun is 40 passing navigation/simulation GUI tests. Ruff, Ruff-format, Black,
-pinned MyPy 1.13 across all 18 changed production modules, Bandit, the exact
-18-file 500-line gate, docs, minimum-test, changed-test assertions,
-detect-secrets fingerprints, and staged/unstaged diff checks pass. CPython
-3.10.20 compiles every changed Python file and its dependency-free navigation
-state round-trip passes; 30 compatibility/date-boundary regressions also pass.
-There is no Rust delta from the exact parent, whose 12-test `swing-core`
-evidence remains applicable. Independent staged review found no actionable
-findings after 76 additional focused PyQt/navigation/workspace tests; protected
-exact-head CI and required repository review remain release gates after an
-ordinary guarded push.
-
-## 2026-08-10 PR #4279 fractional-timestamp Python 3.10 repair
-
-Exact-head CI on descendant PR #4281 exposed one remaining workspace parser
-difference: CPython 3.10 accepts only three or six fractional-second digits in
-`datetime.fromisoformat`, while newer supported interpreters accept the
-one-digit value already used by the workspace ordering contract. The earliest
-owner is PR #4279. Its shared workspace validator now enforces one anchored UTC
-grammar and parses zero through six fractional digits consistently, rejecting
-greater precision instead of silently truncating it on newer Python versions.
-UTC-only validation, serialized values, schema fields, and chronological
-comparison are unchanged.
-
-Evidence is `778 passed` for the full Rate suite and `45 passed` for the
-compatibility plus complete workspace document suites on the local supported
-interpreter, plus `27 passed` for the source-level compatibility suite on real
-CPython 3.10.20. The latter has only expected warnings for plugins absent from
-that intentionally minimal runtime. Ruff, formatting, pinned mypy 1.13,
-documentation governance, and the 400-line budget pass. Exact remote-head
-identity and normal publication/descendant propagation remain release gates.
-
-## 2026-08-09 PR #4281 scalar-ensemble parent propagation
-
-Draft PR #4281 remains on `feat/4199-wind-scalar-adapter` with unchanged base
-`feat/4144-variation-export-continuation`. Exact corrected #4280 parent
-`38ed58cab96842a3007e76a855db83ee2452b8fd` is incorporated by the normal
-merge containing this handoff; no branch was rebased, retargeted, force-pushed,
-or published by this continuation. The result preserves the complete parent
-workspace, Python 3.10 compatibility, and variation-export history together
-with #4281's independently owned scalar-ensemble and wind-strategy adapters.
-
-The child supplies matching UI-neutral Python/TypeScript
-`scalar-ensemble/v1` contracts with stable RFC3986 composite row identity,
-immutable nullable rows, and overall/per-cohort availability. Its wind adapter
-retains every actual and perfect-information status and exposes true/estimated
-wind, launch/aim, target, landing, miss, cost, and information delta. Impact
-variables remain explicitly unavailable because the analysis starts at
-prescribed launch. SPEC 1.14.12 records this child source delta separately
-from parent versions 1.14.11 and earlier.
-
-Current focused evidence is `49 passed` on Python 3.11 and `49 passed` on real
-CPython 3.10.20 with PyQt6/scientific dependencies present. React passes `2
-files / 10 tests`, TypeScript, and focused zero-warning ESLint. Ruff
-check/format passes the four child Python files; pinned mypy 1.13 passes both
-production modules and the corrected wind-adapter test. Documentation
-governance, ancestry/SPEC assertions, and final diff checks are required in
-this same local merge. Protected CI, review, publication, and descendant
-propagation remain separate release gates. The background runner, progress and
-cancellation, PyQt6/React strategy/scatter workflow, persistence, and export
-wiring remain incomplete and must not be represented as delivered.
-
-## 2026-08-09 PR #4280 parent propagation and SPEC restoration
-
-Draft PR #4280 remains on `feat/4144-variation-export-continuation` with base
-`feat/4218-toolstrip-workspace`. Exact corrected parent
-`3f67ed466fefc8991db9c4409f921f25e1c37142` is incorporated by the normal
-merge containing this handoff; no branch was rebased, retargeted, force-pushed,
-or published by this continuation. The result retains the complete workspace
-and Python 3.10 compatibility history together with #4280's independently
-owned variation scatter/export changes.
-
-The child exports every selected scatter axis to CSV with stable trial index,
-typed outcome, and explicit unavailable values in both PyQt6 and React. PyQt6
-also exposes the selected raw rows in bounded accessible tables, with shared
-table population and focused scatter/matrix modules. SPEC 1.14.11 now records
-this child source delta separately from parent versions 1.14.10 and earlier.
-
-Current evidence is `46 passed` on Python 3.11 and `19 passed` on real CPython
-3.10.20 with PyQt6 present. React passes `1 file / 8 tests`, TypeScript, and
-focused zero-warning ESLint. Ruff check/format passes five child Python files;
-pinned mypy 1.13 passes the four child production modules. Documentation
-governance, ancestry/SPEC assertions, and final diff checks pass locally.
-Protected CI, review, publication, and descendant propagation remain separate
-release gates.
-
-## 2026-08-09 PR #4279 Python 3.10 compatibility completion
-
-Draft PR #4279 remains on `feat/4218-toolstrip-workspace` with unchanged base
-`feat/4181-launch-monitor-registry`. Exact corrected parent
-`08a2fdd8ce6bbc8fbb8f121927a677d4addb6b11` was incorporated by the normal
-local merge `a340fabefa443d47325c5538f342683b38c01ade`; no branch was rebased,
-retargeted, force-pushed, or published by this continuation.
-
-The child-owned command registry and view-workspace enums now obtain
-`StrEnum` from `shared.python.compatibility` at runtime while retaining the
-native type behind `TYPE_CHECKING`. Workspace timestamp validation likewise
-uses the shared `UTC` value. This removes all three Python 3.11-only imports
-introduced by #4279 without changing command IDs, enum values, timestamp
-serialization, workspace schemas, or UI behavior. The merged regression
-guards nine string-enum modules and both UTC modules by inspecting the actual
-runtime import branch, then executes the three child workspace modules.
-
-Evidence is `126 passed` on Python 3.11, plus `14 passed` and a successful
-10-module dotted-import probe on real CPython 3.10.20. Ruff check/format passes
-the 11 production modules and compatibility test; pinned mypy 1.13 passes all
-11 production modules with the changed-file CI settings. Documentation
-governance and final diff checks must pass in this same local commit. Protected
-CI, review, publication, and descendant propagation remain separate gates.
-
-## 2026-08-09 PR #4279 launch-registry propagation
-
-Draft PR #4279 remains on `feat/4218-toolstrip-workspace` with unchanged base
-`feat/4181-launch-monitor-registry`. Exact parent head
-`08a2fdd8ce6bbc8fbb8f121927a677d4addb6b11` is incorporated through the normal
-merge commit containing this handoff; neither branch was rebased, retargeted,
-force-pushed, or pushed by this continuation. Source changes applied cleanly;
-the overlapping handoff and specification histories were reconciled
-monotonically. The result preserves the parent's package-relative facade and
-Python 3.10 enum repairs plus the child's workspace, toolstrip, playback, plot,
-and module-navigation implementation.
-
-Focused validation is `126 passed` across both facade contract modules and all
-Python/PyQt test files changed by #4279. React workspace validation is `8 files
-/ 32 tests passed`. Ruff check and format pass for all 28 relevant Python
-files. CI-pinned mypy 1.13 passes the 18 changed production files plus the two
-facade contract tests. The type gate exposed one real child-boundary defect:
-`legend_visible()` returned an untyped Qt value; it now converts that value at
-the widget boundary with `bool(...)`. The affected simulation GUI rerun is `29
-passed`; documentation governance and staged/unstaged diff checks also pass.
-
-## 2026-08-10 Second Parent Repair Propagation (#4202 -> #4203)
-
-- Draft child PR `#4203` retains base `feat/4189-dplane` and receives exact
- repaired parent head `7d8d2f06dc797021d01939691e58f8425b652b33`
- through a normal merge commit; no base, parent history, or draft state is
- rewritten.
-- The propagated parent repair adds explicit NumPy ndarray result boundaries
- to the two D-plane helpers that failed the hosted pinned MyPy gate. Numerical
- behavior, frames, schemas, and UI behavior remain unchanged.
-- The exact parent quality gate is green. Protected child checks, review, and
- all earlier dependency gates remain open; this propagation does not
- authorize a merge or close #4189.
-- Child-tree verification after conflict reconciliation is 25 focused D-plane,
- impact-contract, impact-kinematics, and impact-scene tests; docs governance,
- changed-file size budget, and whitespace checks also pass. The Windows
- unpinned MyPy 1.15 environment cannot parse the installed Python-3.12-only
- NumPy stub syntax under this branch's Python 3.11 target, and WSL currently
- fails to start with `E_FAIL`; neither attempt is reported as a passing gate.
diff --git a/SPEC.md b/SPEC.md
index 071cdeb96..4c64c7e88 100644
--- a/SPEC.md
+++ b/SPEC.md
@@ -26,162 +26,14 @@
| **Owner** | D-sorganization |
| **Primary Language(s)** | Python 3.11+, Rust, JavaScript, TypeScript |
| **License** | MIT |
-| **Current Version** | 1.14.31 |
-| **Spec Version** | 1.14.31 |
+| **Current Version** | 1.14.35 |
+| **Spec Version** | 1.14.35 |
| **Last Spec Update** | 2026-08-11 |
## 2. Purpose & Mission
Comprehensive monorepo housing 45+ utility tools for data processing, scientific computing, process engineering, and automation. This is the central tooling hub for the D-sorganization fleet, providing modular engineering calculation tools with PyQt6 GUIs, FastAPI web services, Rust numerical kernels, and a unified launcher with plugin architecture for extensibility.
-### 2026-08-11 PR #4288 append-only history preservation repair
-
-The documentation-only follow-up to exact local candidate
-`1eb4188ff1a87a3d8e9a55aeca68194ca04e0bb4` restores parent handoff sections
-and change-log rows omitted during reconciliation and repairs one interleaved
-handoff paragraph. Production code, tests, schemas, the campaign manifest,
-child-first merge topology, and PR #4288's `feat/4268-ground-contract` base are
-unchanged. Publication and protected exact-head release evidence remain open.
-
-### 2026-08-11 Ground contract receives current workflow/base ancestry
-
-- Exact remote ground-contract child
- `7a38b9838d743e051a6900620c4d6e754582aa89` is the first parent and exact
- published workflow/base head
- `b2baf6ef615b0d756a86ac4ca7eef2fc583210ee` is merged second, preserving
- PR #4285's `feat/4197-capability-observer` base and child-first topology.
-- The strict `flight-to-ground/v1` contract remains behaviorally unchanged
- while inheriting the current wind/capability stack, Ground/Tee parity, split
- kinetics facade, and pinned formatting repairs. The ground-side kinetics
- conflict was an obsolete formatting-only edit and contributes no behavior.
-- The retained scalar extractor narrowing is housed behind a 61-line public
- plotting catalog facade. Ordered scalar and series entries are separated in
- private collaborators, keeping every changed production module/function/
- signature within 400 lines, 50 lines, and four non-receiver parameters while
- preserving catalog keys, order, categories, units, and extractor behavior.
-- Verification passes the complete 1,539-test Rate/shared-swing Python matrix
- with one optional Rust-wheel skip, all 648 React tests in 106 files,
- TypeScript, zero-warning ESLint, the 188-module production build, 12 Rust
- tests, 146 focused contract/parity tests, and 57 catalog/plot regressions.
-- This merge creates a local publication candidate only. Bounce, skid, roll,
- terrain profiles, total distance, ground UI, Rust/WASM ground parity,
- protected CI, approval, release, and downstream #4288 propagation remain
- explicitly open.
-
-### 2026-08-11 Wind workflow receives current scalar-adapter parent
-
-- The responsive PyQt6/React wind-strategy workflow and consolidated
- capability stack inherit exact scalar-adapter parent
- `a7dce5f89b483303938f518b74b4028a1c68ba81` through a normal child-first
- merge, preserving branch topology and both histories.
-- The validated split kinetics facade replaces one obsolete child formatting
- hunk. Seven remaining child-owned paths receive pinned Ruff formatting only;
- physics, public APIs, schemas, frames, units, and UI behavior are unchanged.
-- The exact skipped-import MyPy profile replaces one unused cache-return ignore
- with an explicit `KineticsSeries | None` cast. The cached object and runtime
- behavior are unchanged.
-
-### 2026-08-11 Wind strategy plot-adapter module-budget repair
-
-- `rate_of_closure.variation.wind_strategy_plot_adapter` remains the public
- plot-data facade. Its request/analysis validation is delegated to the private
- `_wind_strategy_plot_validation` collaborator so both production modules are
- below the mandatory 400-line ceiling.
-- The public API, `scalar-ensemble/v1` wire shape and ordering, row identity,
- values, typed availability, attributes, validation messages, and contract
- prohibiting a flight-physics rerun are unchanged.
-- Private wind-scenario validation receives a scenario and one frozen, slotted
- expectation object, keeping every production function at or below four
- parameters and 50 lines without weakening any precondition.
-
-### 2026-08-11 Kinetics module-budget repair
-
-- The established `rate_of_closure.simulation.kinetics` module remains the
- public façade for swing kinetics. Immutable result validation now lives in
- `_kinetics_series.py`, and pure double-pendulum inverse/forward dynamics and
- reaction-force helpers live in `_kinetics_dynamics.py`.
-- Public constants, classes, and functions retain identity-preserving imports;
- the historical private `_reaction_forces` test/consumer seam remains an
- alias to the extracted implementation. Physics, SI units, frames, numerical
- fixtures, UI behavior, and serialization contracts are unchanged.
-- This extraction repairs the proactively reproduced changed-file failure:
- exact head `572bf525d` versus `HEAD~1` selected the Ruff-formatted
- `kinetics.py` at 646 LOC, above the ungrandfathered 500-LOC ceiling. The
- façade and its focused implementation modules are now 222, 205, and 131 LOC.
-
-### 2026-08-09 Capability workflow contract hardening
-
-- Python and TypeScript capability workflow readers reject JSON primitive type
- mismatches throughout the nested v1 document instead of coercing numeric
- strings, booleans, or numeric text fields.
-- A shared golden parser fixture pins identical acceptance and rejection,
- including portable acceptance of mathematically integral JSON numbers for
- integer fields.
-- React Shot Optimizer numeric controls retain decimal draft text, allowing
- ordinary leading-minus keyboard entry before validated numeric commit.
-
-### 2026-08-09 Capability result diagnostics
-
-- PyQt6 and React ranked-alternative views expose the full v1 optimization
- diagnostics, explicit parameter units, evidence-envelope state, and Pareto
- state rather than a reduced carry/dispersion summary.
-- Ranked results export through spreadsheet-safe CSV and a deterministic
- `capability-result-export/v1` JSON envelope. Lossless raw observation exports
- remain separate so aggregate recommendations cannot obscure failed or
- no-impact trials.
-- React scalar-ensemble scatter plots render numeric grid/tick scales, visible
- axis ranges, and cohort legends with paired-finite counts.
-
-### 2026-08-09 Rate campaign release-evidence authority
-
-- `docs/release/rate_of_closure_campaign.v1.json` is the normalized authority
- for primary campaign issues, specifications, carriers, four-surface support,
- commit-bound tests, limitations, dependencies, and release status.
-- `scripts/rate_campaign_manifest.py` validates the strict version-1 contract
- and emits its deterministic JSON Schema. Feature-stack implementation,
- protected parent integration, and exact `main` release are mutually
- exclusive states with fail-closed cross-field requirements.
-- The current manifest truthfully records no complete campaign release SHA;
- local tests and unprotected feature-parent merges cannot satisfy that claim.
-- Composed local implementation evidence is commit-bound in the manifest;
- maintainers must still refresh live mutable PR heads before any write,
- merge, release, or issue-closure decision.
-- The manifest loader explicitly narrows Pydantic's validated value for the
- CI mypy 1.13 `--follow-imports=skip` context without weakening runtime
- validation or the generated schema.
-- The PyQt playback adapter similarly converts Qt's elapsed-time result to a
- concrete `float`, preserving the typed seconds contract when Qt imports are
- deliberately skipped by the changed-file CI lane.
-
-### 2026-08-09 Swing-core parity CI isolation
-
-- The dedicated `swing_core` Rust-to-Python parity lane disables third-party
- pytest plugin auto-loading so cached GUI plugins on self-hosted runners cannot
- introduce undeclared PyQt dependencies into the Rust-only qualification job.
-- The lane continues to install the built wheel and run the same non-skippable
- parity suite; numerical behavior and production dependencies are unchanged.
-
-### 2026-08-09 Rate web-release stability
-
-- The documented direct Rate web launcher imports its registration through the
- package-qualified path and dynamically loads the repository bootstrap without
- direct `sys.path` mutation, so `python src/rate_of_closure/launch_web.py`
- works outside package-module execution and satisfies changed-file policy.
-- Rate supports a static Vite web release and a PyQt6/PyInstaller desktop
- release. It does not claim Tauri support without a `src-tauri` project or an
- artifact qualification lane.
-- The Flight Explorer parent-panel test explicitly settles its lazy wind-panel
- import inside React `act`, removing suite-load timing from the assertion.
-
-### 2026-08-10 D-plane ndarray typing boundary repair
-
-- The private D-plane vector conversion and horizontal-projection helpers bind
- NumPy expression results to explicit ndarray locals before returning them.
-- This preserves the existing numerical calculations and DbC validation while
- satisfying the changed-file MyPy `no-any-return` contract on Python 3.12.
-- No public API, reference frame, serialized schema, physics assumption, or UI
- behavior changes in this repair.
-
### 2026-08-06 GUI module-budget repair
- Movement Optimizer motion palette and chain-length helpers live in a small
@@ -194,7 +46,7 @@ unchanged. Publication and protected exact-head release evidence remain open.
## 3. Goals & Non-Goals
-### 2026-08-10 Regional Surface-Plan Editor First Slice
+### 2026-08-10 Regional Surface-Plan Canonical Request I/O
- The standalone PyQt6 and React shells expose matched `Ground Surfaces`
modules for editing one SI base domain and one to eight coplanar static
@@ -208,9 +60,28 @@ unchanged. Publication and protected exact-head release evidence remain open.
errors preserve the draft and provide accessible error state; successful
validation exposes schema, SI-unit, provenance, and canonical request
readback.
-- This first slice is session-only. Ground execution/playback, result import,
- export, measured calibration workflows, model-input persistence, compiled
- regional physics, and UpstreamDrift consumers remain explicit non-goals.
+- Native PyQt6 Open/Save As commands use strict complete-read validation and
+ atomic UTF-8 replacement. Browser import/download uses the same bounded
+ canonical request and discloses that browser downloads cannot guarantee a
+ path, atomic replacement, or recent-file access. Workspace persistence is a
+ separate contract.
+- Imports accept only editor-v1 provenance, providers, geometry/axis
+ qualification, and row capacity. Unchanged imports preserve the exact
+ request and provenance; edits create a fresh draft digest. External or
+ differently qualified requests are rejected without coercion.
+- Both runtimes accept wire numbers only inside JavaScript's exact safe range.
+ Native precedence entry remains integer-exact through the inclusive v1
+ maximum of 9,007,199,254,740,991 and cannot silently narrow imported data.
+- Native request import reads a single binary-handle snapshot bounded to the
+ 1 MiB wire limit plus one sentinel byte, then performs strict UTF-8 decoding.
+ Concurrent file growth cannot trigger an unbounded allocation.
+- PyQt6 canonical-precision inputs share one frozen `NumberInputSpec` and
+ three-parameter construction helper. The regional I/O editor retains its
+ eleven-decimal presentation and inclusive cross-runtime safe bounds without
+ restoring the superseded six-parameter helper.
+- Ground execution/playback, result interchange, measured calibration
+ workflows, model-input workspace persistence, compiled regional physics,
+ and UpstreamDrift consumers remain explicit non-goals.
### 2026-08-06 Impact-to-Flight Solution-Family Foundation
@@ -457,15 +328,6 @@ unchanged. Publication and protected exact-head release evidence remain open.
overrides survive club changes, legacy runs migrate to Ground, and the
derived ball center drives contact, alignment, impact records, flight origin,
and both standalone renderers.
-- Python and React consume the same version-1 golden ball-setup fixture. Its
- strict metadata fixes SI metre units and the
- `ground_plane_to_ball_bottom` reference; its cases pin club defaults,
- explicit overrides, Ground's zero effective tee height, derived geometry,
- serialization, invalid-height rejection, and legacy migration.
-- Visual verification uses semantic state and structural image contracts, not
- pixel-perfect baselines: Playwright records default Tee and rerun Ground web
- states with zero browser errors, while the hidden-window PyQt harness pins
- canonical center/artist state and nonblank, distinct Ground/Tee captures.
- Variation plans retain their complete v2 schema and can be saved, loaded,
duplicated, and deleted from a versioned local library. Users can select
simultaneous, one-at-a-time, or combined analyses, while paired common-
@@ -3073,32 +2935,24 @@ Active development with stable core, continuous tool expansion, and web API in p
| Date | Version | Changes |
| ---- | ------- | ------- |
+| 2026-08-11 | 1.14.35 | fix(rate-of-closure, #4342): retain the default canonical JSON encoder's JavaScript-safe numeric boundary for ground contracts while adding an explicit capability-observation-only extended finite-float policy that reuses the same recursive encoder; keep integers safe-range bounded, emit integral finite doubles such as `1e20` and `1e21` as exact exponent-free decimal tokens matching the TypeScript capability serializer, and preserve fail-closed non-finite handling with Python, TypeScript, ground-boundary, full-suite, static-analysis, build, and governance evidence. |
+| 2026-08-11 | 1.14.34 | merge(rate-of-closure, #4274 #4339 #4342): normally merge exact current regional request-I/O child `c1f47f2ef68b3db102da5416aaac17a40f675207` first with exact reviewed local regional-editor parent candidate `db335937afc4b587d235eb705e315f577519c5e6` second while preserving PR #4342's `feat/4274-regional-surface-ui` base, child-owned canonical request import/export, bounded UTF-8 and safe-number validation, native atomic save, browser-qualified download, tests, limitations, and all append-only handoff/SPEC history; inherit current editor, wire, regional-physics, and complete ground ancestry without rebase, retarget, rewrite, force-push, or publication, while keeping execution/playback, result interchange, measured calibration, model-input persistence, changing geometry or velocity, TypeScript/compiled regional physics, downstream parity, protected exact-head evidence, review, approval, dependency integration, and release open. |
| 2026-08-11 | 1.14.31 | merge(rate-of-closure, #4274 #4335 #4339): normally merge exact current regional-editor child `d21741e312b849a63f73cabf351a15d9de80fb94` first with exact published regional-wire parent `8f933ed8dcb29e55ece4ec6bb1e60813f6794d57` second while preserving PR #4339's `feat/4271-regional-wire-contract` base, matched PyQt6/React editors, strict validation invalidation and readback, parent wire/resolver/regional-physics/ground ancestry, and both append-only handoff/SPEC histories; retain the extracted navigation-state contract with `regional_surfaces` in default and legacy migration order, without rebase, retarget, rewrite, force-push, or publication, while keeping execution/playback, result interchange, measured calibration, model-input persistence, changing geometry or velocity, TypeScript/compiled regional physics, downstream parity, protected exact-head evidence, review, approval, dependency integration, and release open. |
+| 2026-08-11 | 1.14.33 | docs(rate-of-closure, #4342): restore verbatim the omitted PR #4335, #4332, and #4304 current-parent ancestry sections in all three canonical handoffs and the parent's exact parallel-branch SPEC 1.14.29 and 1.14.28 reconciliation rows; record the historical version collision without rewriting either branch's append-only record; change no production code, tests, schemas, manifest state, PR base, protected evidence, or release status. |
+| 2026-08-11 | 1.14.32 | chore(rate-of-closure, #4274 #4342): normally reconcile exact published regional request-I/O child `8e1c7ccd99a7c4886c5fb9ccc7e4d94a6d7e3833` with exact newly published regional-editor parent `d21741e312b849a63f73cabf351a15d9de80fb94` without changing PR #4342's base; preserve native atomic and browser-qualified canonical request I/O, safe-number and bounded UTF-8 behavior, and the parent's frozen validated engineering-number specification by delegating child controls to its three-parameter helper while retaining eleven-decimal presentation; keep protected CI, approval, integration, execution, calibration, downstream parity, and release open. |
+| 2026-08-11 | 1.14.31 | fix(rate-of-closure, #4274 #4342): remove one redundant Boolean cast rejected by protected delta-MyPy without changing wire bytes, validation, file semantics, UI behavior, or physics. |
| 2026-08-11 | 1.14.30 | fix(rate-of-closure, #4274 #4339): replace the six-parameter PyQt engineering-number helper with a three-parameter helper and frozen validated specification while preserving names, values, units, ranges, increments, tooltips, and field order; add RED-first helper/configuration and structural-bound tests, retain byte-stable wire/digest/physics behavior, and keep protected CI, approval, integration, and release open. |
| 2026-08-11 | 1.14.29 | chore(rate-of-closure, #4274 #4339): normally reconcile exact published regional-surface editor child `cbb9c0a6bdc6a50f59f7a661139b9d53e1892980` with exact newly published regional-plan wire parent `9e01ccc3e891cc45907293751a192624195a77a5` without changing the PR base or rewriting either branch; retain matched PyQt6/React request editors, invalidation and engineering hints together with the strict Python/TypeScript plan contract, resolver binding, bounded coplanar regional physics, and complete ground ancestry, while preserving execution/playback, result interchange, measured calibration, workspace persistence, changing geometry, compiled-runtime physics, downstream parity, protected evidence, and release as open work. |
-| 2026-08-11 | 1.14.29 | merge(ground-regional-wire, #4332 #4335): normally merge exact remote regional-wire child `9e01ccc3e891cc45907293751a192624195a77a5` first with exact current regional-surface parent `5ac3c1f233de30dd42eeac57073cbdb149bde652` second while preserving PR #4335's `feat/4271-regional-surface-transitions` base, strict Python/TypeScript regional-plan request/result schemas, canonical JSON/SHA-256 fixture evidence, fail-closed parsing, Python resolver binding, tests, limitations, and both append-only handoff/SPEC histories; inherit current regional, skid/roll, impact/bounce, and flight-transfer ancestry without rebase, retarget, force-push, parent rewrite, or remote publication, while keeping changing geometry or velocity, internal transition-ledger export, regional UI, compiled or TypeScript regional physics, downstream parity, protected exact-head CI, review, approval, and release open. |
| 2026-08-11 | 1.14.28 | chore(ground-regions, #4271 #4335): normally reconcile exact live regional-wire child `74a053d2d544da9f44a88007660ad28c0127f285` with exact newly published regional-surface parent `04ccf08dd990de1cd056a3420e67772773a4be2e` without changing the PR base or rewriting either branch; preserve the strict Python/TypeScript plan wire boundary and Python resolver binding together with the parent's reconciled coplanar regional physics and complete skid/roll ancestry, while retaining protected CI/review, UI, compiled or TypeScript regional physics, changing geometry/velocity, internal transition-ledger export, downstream parity, and release as open work. |
+| 2026-08-10 | 1.14.29 | feat(rate-of-closure, #4274): add strict matched PyQt6 native atomic Open/Save As and React bounded import/canonical download for editor-qualified regional requests; preserve exact unchanged provenance, rebind edited drafts, reject unsupported qualifications without coercion, keep workspace persistence separate, and retain execution, calibration, protected evidence, and release as open work. |
+| 2026-08-10 | 1.14.28 | feat(rate-of-closure, #4274): add matched PyQt6 and React regional surface-plan editors with explicit SI material inputs, one-to-eight bounded overlays, illustrative/unvalidated and persistence/execution qualifications, accessible strict validation/readback, provenance bound to the actual draft, and delegation to the separate regional-plan v1 wire contract; retain playback, execution, result interchange, measured calibration, workspace model-input persistence, other runtimes, protected evidence, and release as open work. |
| 2026-08-10 | 1.14.27 | feat(ground-roll, #4271): add separate strict Python/TypeScript `ground-regional-material-plan-request/v1` and result/v1 wire contracts with exact keys, SI units, explicit coplanar/static limitations, finite bounded base/overlay intervals, bounded region/document counts, unique region/precedence/surface identities, canonical cross-runtime JSON/SHA-256 evidence, fail-closed no-fabrication result binding, and a Python-only adapter into the existing regional resolver; preserve the frozen flight-to-ground v1 request/result and retain TypeScript/compiled regional physics, UI, changing geometry, internal transition-ledger export, downstream parity, protected CI, review, and release as open work. |
| 2026-08-10 | 1.14.26 | feat(ground-roll, #4271): add bounded Python-reference support for finite coplanar material overlays with unique explicit precedence, exact quadratic boundary splitting, base-edge precedence, state/energy continuity, strict Python/TypeScript `surface_transition` events, internal from/to identity evidence, typed transition limits, and randomized piecewise-analytic qualification; reject changing normals, height/velocity discontinuities, and overlays owning the impact handoff rather than fabricating impulses or geometry transitions, while retaining UI, compiled regional physics, and downstream parity as open work. |
-| 2026-08-11 | 1.14.28 | merge(ground-regions, #4304 #4332): normally merge exact remote regional-surface child `04ccf08dd990de1cd056a3420e67772773a4be2e` first with exact current skid/roll parent `3f861c1faaa7455faee92eaa7f813174667208e0` second while preserving PR #4332's `feat/4271-ground-skid-roll` base, bounded coplanar material overlays, exact transition splitting and evidence, regional production, tests, fixtures, contracts, limitations, and both append-only handoff/SPEC histories; inherit current impact, bounce, skid, roll, and flight-transfer ancestry without rebase, retarget, force-push, parent rewrite, or remote publication, while keeping changing normals, discontinuous geometry or velocity, regional UI, compiled regional physics, downstream parity, protected exact-head CI, review, approval, and release open. |
-| 2026-08-11 | 1.14.27 | chore(ground-regions, #4271 #4332): normally reconcile exact live regional-surface child `1a48d749af508843fac2a5102f4dd56294429bda` with exact newly published skid/roll parent `0ea6740965068542e9d8c7449e06ec07d88969e0` without changing the PR base or rewriting either branch; preserve bounded coplanar material overlays, exact transition splitting and evidence, strict contracts, and all current parent physics while retaining changing normals, discontinuous geometry/velocity, UI, compiled regional physics, and downstream parity as open work. |
-| 2026-08-11 | 1.14.27 | merge(ground-roll, #4302 #4304): normally merge exact remote skid/roll child `0ea6740965068542e9d8c7449e06ec07d88969e0` first with exact current impact/bounce parent `62beb3e1aa951645fd556a53f9cbae4bb46c47e5` second while preserving PR #4304's `feat/4270-ground-impact-bounce` base, arbitrary-plane skid, static-feasible pure roll, rolling resistance, qualified rest, edge localization, strict result composition, passive ledgers, fixtures, tests, limitations, and both append-only histories; inherit current bounce and flight-transfer ancestry without rebase, retarget, force-push, parent rewrite, or remote publication, while keeping regional/changing-normal surfaces, deformation, torsional damping, roll-to-skid transitions, UI, compiled physics, protected exact-head CI, review, approval, downstream integration, and release open. |
-| 2026-08-11 | 1.14.26 | chore(ground-roll, #4271 #4304): fast-forward the local skid/roll carrier to exact live child `52d9a6a978d8e6b8b19ef92f02f265c9058b00ad`, then normally merge exact live impact/bounce parent `cf6e72bad98e5f36f782254942e6895b8b71e670` without changing the PR base or rewriting either branch; retain the reviewed skid/roll physics and strict contracts while reconciling current ancestry and deterministic formatting evidence. |
| 2026-08-10 | 1.14.25 | fix(ground-roll, #4271 #4304): normally propagate exact corrected ground-impact/bounce parent `846653c21bd61a40aab99ab838c29915d0728e70` into the skid/roll descendant without changing its base; preserve the reviewed arbitrary-plane skid, pure-roll, resistance, rest, edge, composition, and passive-ledger behavior while inheriting corrected flight-transfer ancestry, deterministic workspace timestamp parsing, and canonical `swing_sim` import identity; retain explicit exclusions for regional/changing-normal surfaces, terrain deformation, torsional spin damping, roll-to-skid transitions, UI, compiled physics, and downstream parity. |
| 2026-08-10 | 1.14.24 | fix(ground-roll, #4304): explicitly allowlist the immutable SHA-256 golden-fixture digest as non-secret test evidence so protected secret scanning distinguishes a scientific integrity fingerprint from a credential; no physics, numerical, schema, API, or fixture bytes change. |
| 2026-08-09 | 1.14.23 | feat(ground-roll, #4271): continue exact #4270 capture through arbitrary-plane kinetic skid, static-feasible pure roll, rolling resistance, qualified rest, finite-axis edge localization, bounded typed limits, relative surface-path and passive energy ledgers; compose representable prefix/suffix evidence into strict v1 results without duplicate or epsilon-time samples; pin an analytic shared fixture and retain explicit exclusions for regions, changing normals, torsional spin damping, roll-to-skid, UI, compiled runtimes, and downstream parity. |
-| 2026-08-11 | 1.14.26 | merge(ground-impact, #4288 #4302): normally merge exact remote ground-impact/bounce child `cf6e72bad98e5f36f782254942e6895b8b71e670` first with exact current flight-ground-transfer parent `c39297d37a17d5d8d3520ed62c5563cdcc609cab` second while preserving PR #4302's `feat/4269-flight-ground-transfer` base, passive restitution/Coulomb impact, deterministic repeated bounce, exact-contact and capture-to-skid behavior, cancellation/failure evidence, and both append-only histories; apply AST-equivalent pinned Ruff 0.14.10 layout to three inherited PR-delta files; inherit the current transfer and strict-ground ancestry without rebase, retarget, force-push, parent rewrite, or remote publication, while keeping skid, roll, rest, total distance, final ground results, UI, compiled bounce runtimes, protected exact-head CI, review, approval, and release open. |
| 2026-08-10 | 1.14.22 | fix(ground-impact, #4270 #4302): normally propagate exact corrected flight-transfer parent `247215422a6d4b677552955b4923bc609a553259` into the ground-impact/bounce descendant without changing its base; preserve the passive restitution/Coulomb impulse, deterministic repeated hops, exact-contact and capture-to-skid behavior while inheriting deterministic workspace timestamp parsing and canonical `swing_sim` import identity; retain explicit non-delivery boundaries for skid, roll, rest, total distance, final ground results, UI, TypeScript physics, and compiled bounce runtimes. |
| 2026-08-09 | 1.14.21 | feat(ground-impact, #4270): add a typed passive restitution/Coulomb sphere-plane impulse with full spin and moving-boundary accounting, deterministic repeated ballistic hops, exact bracket contact, capture-to-skid handoff, cancellation and bounded failure states, airborne-segment evidence, a shared golden fixture, and analytic/property/convergence tests; retain #4271 ownership of skid, roll, rest, total distance, and final `GroundSimulationResult`, with UI and compiled runtimes explicitly excluded. |
-| 2026-08-11 | 1.14.25 | merge(flight-ground, #4285 #4288): normally merge exact remote flight-ground-transfer child `df716ac740beb9d47dced66f867dc3dde1fa5367` first with exact current strict-ground parent `584e4e53a7990053a346938c4e45538786887ec7` second while preserving #4288's `feat/4268-ground-contract` base, complete Python/TypeScript/Rust/PyO3/WASM transfer production/tests/fixtures/contact evidence, cross-runtime contracts, and explicit incomplete ground-physics/UI/release limitations; retain both append-only histories without rebase, retarget, force-push, parent rewrite, or remote publication, and keep protected exact-head CI, review, approval, and release open. |
-| 2026-08-11 | 1.14.24 | docs(flight-ground, #4285 #4288): restore every parent handoff section and specification history row omitted during the local #4288 reconciliation, repair the interleaved rate-of-closure handoff paragraph, and preserve the exact candidate's implementation, tests, schemas, campaign manifest, child-first topology, and `feat/4268-ground-contract` base; keep publication, protected exact-head CI, approval, dependency integration, and release open. |
-| 2026-08-11 | 1.14.23 | chore(flight-ground, #4285 #4288): normally reconcile exact published flight-transfer child `afb1bdcfc6701caaf1f7bc3497a6a37dd9698c14` with exact newly published strict-ground parent `e09ab96280cab363b36bd0e7db4a3cd064dc2527` without changing #4288's base or rewriting either branch; preserve the child's bounded TypeScript flight integrator, signed terminal angular state, physical sphere/terrain contact, and Python/TypeScript/Rust/PyO3/WASM transfer while inheriting the parent's current wind/capability, strict-ground, split-kinetics, plotting-catalog, and formatting ancestry; apply AST-equivalent pinned Ruff normalization to seven child-owned Python files and standard line endings to the preserved TypeScript facade; retain bounce, skid, roll, terrain response, total distance, UI, protected evidence, and release as open work. |
-| 2026-08-11 | 1.14.24 | merge(rate-of-closure, #4283 #4285): normally merge exact remote ground-contract child `e09ab96280cab363b36bd0e7db4a3cd064dc2527` first with exact current capability-observer carrier `d0b827667e61f0583e1dad0b3cbbca6819624d3c` second while preserving #4285's `feat/4197-capability-observer` base, complete strict `flight-to-ground/v1` production/tests/schemas/fixtures/dependencies, fail-closed unimplemented-physics boundary, and both append-only histories; inherit current wind/capability/release ancestry without rebase, retarget, force-push, parent rewrite, or remote publication, and keep protected exact-head CI, review, approval, release, and normal downstream #4288 propagation open. |
-| 2026-08-11 | 1.14.22 | merge(rate-of-closure, #4282 #4283 #4285): normally merge exact remote ground-contract child `7a38b9838d743e051a6900620c4d6e754582aa89` first with exact current workflow/base head `b2baf6ef615b0d756a86ac4ca7eef2fc583210ee` second, preserving PR #4285's base and strict flight-to-ground contract while inheriting the complete current wind/capability, Ground/Tee parity, split-kinetics, and pinned-format ancestry; resolve the obsolete formatting-only kinetics hunk wholly to the validated parent facade, retain both append-only histories, and keep protected CI, approval, publication, release, qualified ground physics, and downstream #4288 propagation open. |
-| 2026-08-10 | 1.14.19 | fix(rate-of-closure, #4282 #4285): normally propagate exact quality-green responsive wind-workflow head `1e82f15026786ea0b08f78f4c001590ddce9ff39` into strict flight-to-ground contract child `e5bcbd1096d3be1f621a805c9d9f3fd321e375a5` without production/test conflict, topology change, or history rewrite; retain the fail-closed contract boundary and require fresh CI/review before normal #4288 propagation. |
-| 2026-08-10 | 1.14.18 | feat/fix(ground, #4199 #4268 #4282 #4285): normally propagate exact repaired responsive wind-workflow carrier `686016196a2f895058b8a566dff103a0fd32cd10` into original strict ground-contract child `788aa547651a3685a363ea401824a5d81477bafb` while preserving base `feat/4197-capability-observer`; retain the fail-closed ground schemas, fixture, migrations, legacy adapter, explicit dependency, import-alias repair, and pinned typing repairs while inheriting the complete deterministic workspace, variation, scalar-wind, capability, campaign-release, and hosted-mypy manifest-repair ancestry; normalize contract-checked scalar plot extraction so the composed skipped-import mypy profile cannot leak `Any`, enforce disabled-command invariants under optimized Python, and document the optional alias finder's reviewed catch-and-continue security boundary; preserve the established no-bounce/no-skid/no-roll/no-terrain/no-total-distance/no-ground-UI/no-Rust-WASM delivery boundary and require #4288 to acquire this exact ancestry through its own normal descendant merge. |
-| 2026-08-10 | 1.14.22 | fix(flight-ground, #4285 #4288): normally propagate exact quality-green strict-ground-contract head `a93edb4bfd6a8dc9334122cd2ae660983d5bf424` into flight-transfer child `108a841b1378c992defd3c7b7ee263d41a6c8b24` without production/test conflict, topology change, or history rewrite; retain the qualified cross-runtime transfer and explicit non-delivery boundaries, with fresh CI/review required before release. |
-| 2026-08-10 | 1.14.21 | fix(flight-ground, #4199 #4269 #4282 #4285 #4288): normally propagate exact repaired strict-ground parent `e5bcbd1096d3be1f621a805c9d9f3fd321e375a5` into original flight-transfer child `247215422a6d4b677552955b4923bc609a553259` while preserving base `feat/4268-ground-contract`; retain the qualified signed terminal state, physical sphere/terrain contact brackets, strict provenance, and Python/TypeScript/Rust/PyO3/WASM transfer while inheriting the deterministic workspace, variation, scalar-wind, capability, campaign-release, hosted-mypy, import-identity, scalar-extraction, command-invariant, and security-boundary repairs; preserve explicit non-delivery boundaries for bounce, skid, roll, terrain response, total distance, and UI. |
| 2026-08-10 | 1.14.20 | fix(flight-ground, #4269 #4288): normally propagate exact corrected ground-contract parent `788aa547651a3685a363ea401824a5d81477bafb` into the flight-transfer descendant without changing its base; preserve the qualified Python/TypeScript/Rust/PyO3/WASM transfer while inheriting deterministic workspace timestamp parsing and canonical `swing_sim` import identity; retain explicit non-delivery boundaries for bounce, skid, roll, terrain response, total distance, and UI. |
| 2026-08-09 | 1.14.19 | chore(flight-ground, #4269 #4288): normally propagate exact carrier-reconciled ground parent `6a2bc9d06f6f9a28a0d615b19d2ed4fc13871059` into the flight-transfer descendant without changing its base; preserve the qualified cross-runtime transfer and semantic facade assertions while completing corrected wind-to-ground ancestry; bind terminal samples before exact `FlightStatePoint` narrowing in the pinned-mypy regression; and retain explicit non-delivery boundaries for bounce, skid, roll, terrain response, total distance, and UI. |
| 2026-08-09 | 1.14.18 | feat(flight-ground, #4269): propagate full signed terminal angular state and qualified physical sphere/terrain contact brackets across Python, TypeScript, Rust, PyO3, and WASM; preserve exact launch-origin evidence, vertical tee and terrain geometry, strict v1 surface/calibration/provenance data, interpolated terminal contact, typed unavailable outcomes, and bounded synchronous web integration. Reconcile the transfer integrator with the current capability and strict-ground ancestry through normal stacked merges without retargeting or rewriting either PR, and remove the resulting ground/flight package-facade cycle through direct record/type dependencies. |
@@ -3109,55 +2963,12 @@ Active development with stable core, continuous tool expansion, and web API in p
| 2026-08-10 | 1.14.13 | fix(rate-of-closure, #4282): normally propagate exact corrected scalar-ensemble parent `cf52529b1e68479321bb93b1be3d59c77f782008` into the responsive PyQt6/React wind-workflow carrier without changing its base; retain the consolidated capability workflow and release authority while inheriting the strict cross-version UTC parser, variation export, immutable scalar rows, stable composite identity, availability, and typed wind adapter; route the child-owned capability-observation `StrEnum` through the shared Python 3.10 runtime contract and extend the compatibility regression. |
| 2026-08-10 | 1.14.12 | feat(wind variation, #4199 #4281): add matching UI-neutral Python/TypeScript `scalar-ensemble/v1` contracts with structured provenance, labeled stages/categories/cohorts, unit-bearing variables, stable RFC3986 composite row IDs, immutable nullable raw rows, and overall/per-cohort availability; adapt every actual and perfect-information wind-strategy outcome with explicit status, true/estimated wind, launch/aim, target, landing, miss, cost, and information-delta values while leaving impact variables explicitly unavailable because the analysis begins at prescribed launch. |
| 2026-08-10 | 1.14.11 | feat(variation, #4144 #4280): complete PyQt6/React selected-scatter CSV export parity with stable trial identity, typed outcome and explicit unavailable values; expose bounded accessible PyQt raw-row tables through one shared population helper; and split scalar scatter and distribution-matrix rendering into focused modules while preserving linked trial selection and all-trial arc analysis. |
-| 2026-08-11 | 1.14.23 | merge(rate-of-closure, #4282 #4283 #4285): use the already-merged PR #4283 head branch as the preserved dependency carrier for open draft PR #4285; normally merge exact remote/local capability-observer carrier child `b2baf6ef615b0d756a86ac4ca7eef2fc583210ee` first with exact published wind-workflow parent `3faf9e9493c9ba37168d9f65ab10cafeedc2a72f` second without reopening or retargeting a PR or rewriting history; reproduce the exact #4282 implementation while retaining the complete capability-observer history; keep publication, protected exact-head CI, and later #4285 propagation outside the bounded local audit. |
-| 2026-08-11 | 1.14.22 | merge(rate-of-closure, #4281 #4282): normally merge exact published responsive wind-workflow child `b2baf6ef615b0d756a86ac4ca7eef2fc583210ee` first with exact newly published wind scalar-adapter parent `9321c1d2e091b8c7e5a4a83aa9ad726290e7fb5a` second while preserving PR #4282's `feat/4199-wind-scalar-adapter` base and both histories; retain responsive PyQt6/React wind execution, progress/cancellation, controls, scatter, persistence/export, consolidated capability workflow, and strict campaign release authority while inheriting the current scalar-adapter, variation, workspace/toolstrip, launch-monitor/D-plane, split-kinetics, and Qt repairs; keep review, ordinary publication, protected exact-head CI, unresolved-thread checks, dependency integration, and release open. |
-| 2026-08-06 | 1.13.16 | feat(swing_sim, rate_of_closure, #4196): map desired flight to frame-explicit centered driver/iron delivery solution families with strict cross-runtime schemas, observed intervals/correlations, local sensitivities, complete residuals, model manifests, and rejected no-impact/miss diagnostics. |
-| 2026-08-06 | 1.13.15 | feat(swing_sim, rate_of_closure, #4195): add strict desired-flight inverse-solver contracts, deterministic bounded multi-objective search, ranked residual-rich candidates, typed infeasible/no-impact/nonconverged outcomes, and Python/TypeScript parity fixtures. |
-| 2026-08-06 | 1.13.14 | feat(swing_sim, rate_of_closure, #4194): add the canonical source-backed flight-result metric catalog, analytic landing/trajectory derivation, typed unavailable and qualified-ground boundaries, complete run manifests, deterministic Python/TypeScript exports, and cross-client parity fixtures. |
-| 2026-08-11 | 1.14.21 | merge/fix(rate-of-closure, #4281 #4282): normally merge exact published scalar-adapter parent `a7dce5f89b483303938f518b74b4028a1c68ba81` into exact remote responsive-workflow child `29e15d6ff631f7f30afcc745be783f2e716d7dcf` in child-first order; preserve the complete PyQt6/React wind workflow and capability stack while inheriting the parent's split kinetics and scalar-adapter size/parameter repairs; resolve obsolete monolithic kinetics wholly to the parent facade, retain both append-only documentation histories, apply pinned Ruff formatting only to seven surviving child-owned paths, and replace one skipped-import cache-return ignore with an explicit typed cast without changing behavior, APIs, schemas, frames, or units. |
-| 2026-08-10 | 1.14.16 | fix(rate-of-closure, #4281 #4282): normally propagate repaired wind scalar-adapter parent `d6fb04e07c2a625412e9208b07103acdc42c621b` into the responsive wind workflow without production/test conflict or history rewrite; retain current-state handoff policy and verify with 25 focused tests plus governance, size, and whitespace checks. |
-| 2026-08-10 | 1.14.15 | fix(rate-of-closure, #4282): preserve the strict campaign-manifest return contract under the repository's exact pinned-mypy skipped-import profile by explicitly typing the Pydantic-validated local as `CampaignManifest`; this repairs hosted quality-gate run `31395741841` without changing JSON parsing, validation, failure behavior, PR base, or dependency topology, and requires the resulting exact head to propagate normally into #4285. |
-| 2026-08-10 | 1.14.14 | feat/fix(rate-of-closure, #4199 #4281 #4282): normally propagate exact scalar-adapter parent `4a793c4c3f19aad43a3c215800b266be487ace49` into the responsive PyQt6/React wind-workflow carrier without changing its base; preserve the consolidated capability workflow and release authority while inheriting the complete variation, workspace, Python 3.10 compatibility, immutable scalar-row, stable identity, availability, and deterministic wind-scenario repairs; register the child capability tab in the parent's canonical navigation-state tuple so legacy saved orders reveal it without duplicating state; retain runtime invariant enforcement under optimized Python; and satisfy pinned typing/security analysis without weakening the fixed-argument builder boundary. |
-| 2026-08-10 | 1.14.13 | feat/fix(wind variation, #4144 #4199 #4280 #4281): normally propagate exact variation parent `8bcc49fc4e16e5e43be0b7f0f03c3017d5b79d0c` into the wind scalar-adapter child while preserving matching UI-neutral Python/TypeScript `scalar-ensemble/v1` contracts with structured provenance, unit-bearing variables, stable RFC3986 row IDs, immutable nullable raw rows, and overall/per-cohort availability; adapt actual and perfect-information wind outcomes with explicit status, true/estimated wind, launch/aim, target, landing, miss, cost, and information-delta values; enforce the deterministic scenario boundary identically in both clients with exact per-trial provenance, zero shear/turbulence, seed zero, and empty gusts; and retain the parent's result-local linked selection and complete visualization/workspace repairs. |
-| 2026-08-10 | 1.14.12 | feat/fix(variation, #4144 #4218 #4279 #4280): normally propagate exact workspace parent `6717e9e09d507dbc24bedb36177f1cdf0b4fd90b` into the variation-export child while preserving selected-scatter CSV parity with stable trial identity, typed unavailable outcomes, bounded accessible PyQt raw tables, focused PyQt/React visualization modules, linked selection, and all-trial arc analysis alongside the complete workspace/toolstrip, playback, plot, navigation, compatibility, and module-budget repairs; make linked trial selection result-local in both clients, clear it atomically when a rerun replaces the result, and reject or neutralize indices outside the current trial count so smaller reruns cannot crash or dim every new point. |
-| 2026-08-10 | 1.14.11 | feat/fix(rate-of-closure, #4203 #4218 #4279): normally propagate exact launch-registry parent `31cbc007d4c85b5479b7cd0fb0969124eab2af67` into the workspace/toolstrip child while preserving granular playback, path trails, module visibility, and independent plot controls; reuse the parent's single persisted impact-layer mapping and canonical navigation constants without duplicating state; and retain its focused triple-pendulum, plotting-catalog, and primary-navigation repairs. |
| 2026-08-10 | 1.14.10 | fix(compatibility, #4279): make workspace UTC timestamp parsing deterministic across Python 3.10-3.12 with one anchored canonical grammar, consistent zero- through six-digit fractional-second parsing, and rejection of greater-than-microsecond precision instead of interpreter-dependent rejection or truncation. |
| 2026-08-09 | 1.14.9 | fix(compatibility, #4279): route the child command/view `StrEnum` runtime imports and workspace-validation `UTC` import through `shared.python.compatibility` while preserving native enum typing under `TYPE_CHECKING`, all wire values, schemas, UTC serialization, and UI behavior; merge the parent and child regression into one nine-enum/two-UTC runtime-import contract exercised with real CPython 3.10.20. |
| 2026-08-09 | 1.14.8 | feat(rate-of-closure, #4201): harden cross-runtime capability parsing and signed input; expose complete diagnostics, result exports, and quantitative scatter annotations; stabilize supported PyQt6/static-Vite entrypoints; and add a strict campaign manifest with generated schema, four-surface status, explicit gaps/dependencies, and fail-closed feature-stack/protected-parent/`main` release distinctions. |
| 2026-08-08 | 1.14.7 | docs(rate-of-closure, #4197): record the capability stack consolidation onto `feat/4199-wind-workflow`, superseding per-slice stacked-branch cautions after #4283, #4289, and #4294 merged, while retaining the incomplete protected-release boundary. |
-| 2026-08-08 | 1.14.7 | docs(rate-of-closure, #4197): record the capability stack consolidation onto `feat/4199-wind-workflow`, superseding the per-slice stacked-branch cautions now that #4283, #4289, and #4294 are merged, and note that the unfinished CI matrix reflects an offline runner fleet rather than failures. |
| 2026-08-08 | 1.14.6 | feat(rate-of-closure, #4197): add matched PyQt6/React Shot Optimizer workspaces with strict cross-runtime workflow persistence, off-main-thread qualified flight execution, truthful progress/cancellation, complete scalar-ensemble cohort retention, ranked alternatives, stage-qualified selectable scatter axes, zoom/autofit, bounded raw-row paging, lossless CSV/stable JSON, substantive hover guidance, and saved-layout migration that reveals newly registered modules. |
| 2026-08-08 | 1.14.5 | feat(ball-flight, #4197): add profile/request-bound Python and TypeScript Waterloo/Penner capability evaluators with exact established parameter IDs, physical-domain and unit validation, sourced per-club spin defaults or paired variable spin inputs, shared gyro-projected positive-fade/right spin-axis convention across result/impact/variation producers, canonical target-frame conversion, target-aware complete scalar metrics, typed horizon nonconvergence, fail-fast invariants, and a shared 16-scalar tolerance fixture. Corrects the TypeScript ground-crossing interpolation so a descending launch from z=0 cannot extrapolate to a negative sample time, which previously raised an untyped `RangeError` that was absorbed as an `evaluator_exception`; such launches now report `nonconverged`, matching the Python runtime. |
-| 2026-08-11 | 1.14.21 | merge(rate-of-closure, #4280 #4281): normally merge exact published wind scalar-adapter child `a7dce5f89b483303938f518b74b4028a1c68ba81` first with exact newly published variation-export parent `e6c7460a01082631565fb9ed48aa32538bd7772c` second while preserving PR #4281's `feat/4144-variation-export-continuation` base and both histories; retain matching Python/TypeScript `scalar-ensemble/v1` provenance, availability, deterministic-scenario, wind-strategy adapter, and strict module-budget behavior while inheriting current variation visualization/export, workspace/toolstrip, launch-monitor/D-plane ancestry, split kinetics, and behavior-preserving Qt boundaries; keep review, ordinary publication, protected exact-head CI, unresolved-thread checks, dependency integration, and release open. |
-| 2026-08-11 | 1.14.20 | refactor(rate-of-closure, #4281): replace the private wind-scenario validator's five loose parameters with a scenario and one frozen, slotted expectation object; preserve validation order, messages, behavior, public API, and wire output while satisfying the four-parameter and 50-line production-function contracts. |
-| 2026-08-11 | 1.14.19 | refactor(rate-of-closure, #4281): split request/analysis validation from the 403-line wind-strategy plot adapter into a private collaborator, leaving 252-line and 186-line production modules below the mandatory 400-line ceiling while preserving the public API, scalar-ensemble wire order, row identity and values, availability, attributes, validation messages, and no-flight-rerun boundary. |
-| 2026-08-11 | 1.14.18 | merge(rate-of-closure, #4280 #4281): normally merge exact reviewed variation-export parent `3337945699966b63cb5cd8e52d7c3b194315e911` into exact remote wind scalar-adapter child `247046d55afcad3e6cd4f8029f854856c427f59c` with child-first parent order and no history rewrite; preserve matching Python/TypeScript `scalar-ensemble/v1` provenance, availability, deterministic-scenario, and wind-strategy plot-adapter behavior while inheriting the parent variation/export UI, kinetics split, Ground/Tee parity contracts, workspace/toolstrip repairs, and protected Ruff normalization; resolve the obsolete monolithic kinetics overlap to the validated parent `pendulum.sample(...)` facade, retain both append-only documentation histories, and require independent review plus fresh exact-head protected CI before publication. |
-| 2026-08-11 | 1.14.19 | merge(rate-of-closure, #4279 #4280): normally merge exact published variation-export child `3337945699966b63cb5cd8e52d7c3b194315e911` first with exact newly published workspace/toolstrip parent `efbca84095b617b4018732f7802c2da3f0525387` second while preserving PR #4280's `feat/4218-toolstrip-workspace` base and both histories; retain selected-scatter CSV parity, typed unavailable outcomes, bounded accessible tables, linked selection, and all-trial arc analysis while inheriting current workspace, launch-monitor/D-plane ancestry, split kinetics, and behavior-preserving Qt primitive-return boundaries; keep review, ordinary publication, protected exact-head CI, unresolved-thread checks, dependency integration, and release open. |
-| 2026-08-11 | 1.14.17 | merge(rate-of-closure, #4279 #4280): normally merge exact reviewed workspace/toolstrip parent `ccd0e026c580c93038fdf5c59d5d452a85ba27a0` into exact remote variation-export child `668ba96746f79f7a12e8092161bd610054197f58` with child-first parent order and no history rewrite; preserve selected-scatter CSV parity, typed unavailable outcomes, bounded accessible tables, linked selection, and all-trial arc analysis while inheriting the parent kinetics split, Ground/Tee parity contracts, and complete workspace/toolstrip behavior; resolve the obsolete monolithic kinetics overlap to the validated parent façade and normalize seven duplicate automation edits to exact protected Ruff 0.14.10 parent blobs while keeping their commit reachable; require independent review and fresh exact-head protected CI before publication. |
-| 2026-08-11 | 1.14.18 | merge(rate-of-closure, #4203 #4279): normally merge exact published workspace/toolstrip child `ccd0e026c580c93038fdf5c59d5d452a85ba27a0` first with exact newly published launch-registry parent `7abce9ad767fe8311da66a1e5998b892ea3ca9de` second while preserving PR #4279's `feat/4181-launch-monitor-registry` base and both histories; retain workspace, toolstrip, visibility, navigation, playback, and independent-plot behavior while inheriting current launch-monitor/D-plane ancestry, split kinetics, and behavior-preserving Qt primitive-return boundaries; keep review, ordinary publication, protected exact-head CI, unresolved-thread checks, dependency integration, and release open. |
-| 2026-08-11 | 1.14.16 | merge(rate-of-closure, #4279): ordinarily reconcile exact local workspace/toolstrip head `0b22c401a26c31441a599d8d9b39de123706e7ea` with divergent remote automation head `61fe2d556a5413e525d958612ccfd57e65b8d5a2`, preserving every commit and the existing stack topology; recognize 15 already-identical parent paths, normalize seven incompatible formatting edits back to protected Ruff 0.14.10 output, and resolve the sole obsolete pre-split kinetics conflict in favor of the current `pendulum.sample(...)` façade implementation; preserve workspace, toolstrip, visibility, navigation, playback, independent plots, physics, frames, units, schemas, and public contracts; require independent review and fresh exact-head protected CI before publication. |
-| 2026-08-11 | 1.14.15 | merge(rate-of-closure, #4203 #4279): normally propagate exact published launch-registry parent `3796b49e40b677fbac4e05739f8be49f905df2cb` into exact workspace/toolstrip child `7806a16f58e1c6999d32f0127a187fbb21f839a1` without rewriting stack topology; inherit only four static NumPy-array casts while preserving runtime arrays, physics, frames, units, public contracts, workspace behavior, and UI behavior; require fresh current-head protected CI and review. |
-| 2026-08-11 | 1.14.14 | merge(rate-of-closure, #4203 #4279): normally propagate exact launch-registry parent `0216a547aa79727091a2939b96e779e8ddbd7304` into the workspace/toolstrip child without rewriting stack topology; preserve the child's workspace, toolstrip, module-visibility, navigation, playback, and independent-plot behavior while inheriting the parent's identity-preserving kinetics split and pinned formatting repair; require fresh current-head protected CI and review. |
-| 2026-08-11 | 1.14.17 | docs(rate-of-closure, #4202 #4203): restore four exact append-only D-plane parent history rows omitted during the local current-parent reconciliation; preserve the candidate implementation, tests, topology, base, and quality evidence while keeping independent re-review, normal publication, protected exact-head CI, downstream propagation, and release open. |
-| 2026-08-11 | 1.14.16 | fix(rate-of-closure, #4203): close four exact-delta MyPy 1.13 Qt-stub boundaries by narrowing responsive-event handling, legend visibility, ball-setup event filtering, and visible status text to their already declared primitive return contracts; preserve values and UI behavior while retaining normal parent reconciliation and protected release gates. |
-| 2026-08-11 | 1.14.15 | merge(rate-of-closure, #4202 #4203): normally compose exact published launch-monitor-registry child `217e36dc93d30f79826847f958fbcd10805e58ed` with exact current D-plane parent `f3363aa88868f6a5c7e9ccfc682a9eca014e86c1`; retain the split typed kinetics facade at the sole formatting conflict, preserve parent behavior and history, and keep independent review, protected exact-head CI, downstream propagation, and release open. |
-| 2026-08-11 | 1.14.14 | fix(rate-of-closure, #4203): close four hosted MyPy `no-any-return` findings from the kinetics size split with explicit NumPy-array return narrowing at force-norm, RK4 concatenation, and app-frame projection boundaries; preserve exact runtime arrays, physics, frames, units, public contracts, and stack order. |
-| 2026-08-11 | 1.14.13 | refactor(rate-of-closure, #4203): split the 646-LOC swing-kinetics monolith into an identity-preserving 222-LOC public façade, 205-LOC pure-dynamics module, and 131-LOC immutable-series contract; preserve physics, frames, fixtures, UI behavior, and established imports while satisfying the changed-file 500-LOC gate. |
-| 2026-08-11 | 1.14.12 | style(rate-of-closure, #4203): apply repository-pinned Ruff 0.14.10 formatting to the eight files reported by current-head CI without changing physics, behavior, public contracts, schemas, UI layout, or stack order. |
-| 2026-08-10 | 1.14.14 | feat/fix(wind variation, #4144 #4199 #4280 #4281): normally propagate repaired variation parent `b90e5021a59e2081415b51ef29fbed06377bc201` into the wind scalar-adapter child without production/test conflict or history rewrite; preserve matching Python/TypeScript `scalar-ensemble/v1` provenance, availability, deterministic-scenario, and wind-strategy plot-adapter contracts; verify the reconciliation with 25 focused D-plane/impact tests and governance, size, and whitespace gates. |
-| 2026-08-10 | 1.14.13 | feat/fix(variation, #4144 #4218 #4279 #4280): normally propagate repaired workspace parent `61b7f48b5aeb7d57246b4963da3df086e79cbe15` into the variation-export child without feature-code conflict or history rewrite; preserve selected-scatter CSV parity, typed unavailable outcomes, bounded accessible tables, linked selection, all-trial arc analysis, and the complete workspace/toolstrip behavior; verify the reconciliation with 25 focused D-plane/impact tests and governance, size, and whitespace gates. |
-| 2026-08-10 | 1.14.12 | fix(rate-of-closure, d-plane, #4202 #4203 #4279): normally propagate exact repaired launch-registry parent `12dd76a8dbcc106c4683f2f2e53076f8dc6f1b76` into the workspace/toolstrip child without rewriting the stack; inherit explicit ndarray result boundaries while preserving numerical semantics, frames, schemas, and UI behavior; verify the reconciled tree with 25 focused D-plane/impact tests and governance, size, and whitespace gates. |
-| 2026-08-10 | 1.14.11 | feat/fix(rate-of-closure, #4203 #4218 #4279): normally propagate exact launch-registry parent `31cbc007d4c85b5479b7cd0fb0969124eab2af67` into the workspace/toolstrip child while preserving granular playback, path trails, module visibility, and independent plot controls; reuse the parent's single persisted impact-layer mapping and canonical navigation constants without duplicating state; and retain its focused triple-pendulum, plotting-catalog, and primary-navigation repairs. |
-| 2026-08-10 | 1.14.10 | fix(compatibility, #4279): make workspace UTC timestamp parsing deterministic across Python 3.10-3.12 with one anchored canonical grammar, consistent zero- through six-digit fractional-second parsing, and rejection of greater-than-microsecond precision instead of interpreter-dependent rejection or truncation. |
-| 2026-08-09 | 1.14.9 | fix(compatibility, #4279): route the child command/view `StrEnum` runtime imports and workspace-validation `UTC` import through `shared.python.compatibility` while preserving native enum typing under `TYPE_CHECKING`, all wire values, schemas, UTC serialization, and UI behavior; merge the parent and child regression into one nine-enum/two-UTC runtime-import contract exercised with real CPython 3.10.20. |
-| 2026-08-09 | 1.14.8 | feat(rate_of_closure, #4218 #4279): add a UI-neutral File/View/Tools command registry, strict atomic workspace documents, matched PyQt6/React top toolstrips, persistent module visibility and order, direct Impact/Swing/Flight navigation, deterministic replay/loop/speed controls, and independent per-plot canvases with zoom, Auto Fit, and movable or hidden legends. Propagate exact launch-registry parent `08a2fdd8ce6bbc8fbb8f121927a677d4addb6b11` normally while retaining its Linux-safe facade and Python 3.10 compatibility contracts, and type the Qt legend-visibility boundary explicitly for the pinned changed-file mypy gate. |
-| 2026-08-10 | 1.14.11 | test/fix(rate-of-closure, #4143 #4202 #4203 #4325): normally propagate repaired launch-registry parent `12dd76a8dbcc106c4683f2f2e53076f8dc6f1b76` into the shared Ground/Tee parity and rendered-evidence child without production/test-code conflict or history rewrite. |
-| 2026-08-10 | 1.14.10 | test(rate-of-closure, #4143): record deterministic Ground/Tee visual evidence through semantic Playwright checks and a hidden-window PyQt capture regression, retaining screenshots as external digested artifacts instead of brittle pixel baselines or repository binaries. |
-| 2026-08-10 | 1.14.9 | test(rate-of-closure, #4143): add one strict versioned SI golden fixture consumed by Python and React to pin Ground/Tee defaults, explicit overrides, physical height and center geometry, serialization, invalid finite-domain handling, and backward-compatible legacy migration without changing production behavior. |
-| 2026-08-10 | 1.14.8 | feat/fix/refactor(rate-of-closure, #4202 #4203): propagate the exact D-plane parent into the launch-monitor registry without rewriting the stack; preserve the responsive `SimulationViewControlsMixin` architecture while making `ImpactLayerControls` the single owner of persisted D-plane checkbox state; retain the existing automation compatibility seam as an identity alias; and repair the original child's three ungrandfathered size blockers through identity-preserving extractions for triple-pendulum dynamics, immutable plotting metadata, and versioned primary-navigation state. |
-| 2026-08-09 | 1.14.7 | fix(compatibility, #4203): route the PyQt torque-profile controller's UTC constant through the shared Python 3.10 compatibility module, preserving UTC timestamp serialization and workspace behavior while removing the remaining parent-owned `datetime.UTC` collection boundary. |
-| 2026-08-09 | 1.14.6 | fix(compatibility, #4203): route seven Rate/shared swing string-enum runtime imports through the existing Python 3.10 compatibility contract while retaining native enum typing under `TYPE_CHECKING`; preserve all wire values, schemas, physics, and UI behavior, and add a source-level regression exercised with real CPython 3.10.20. |
-| 2026-08-09 | 1.14.5 | fix(ci, #4203): keep the in-package swing flight and solver facade-contract tests in pytest's active package namespace by using relative imports, preventing editable Linux collection from crossing between `src.shared...` and `shared...` before assertions while leaving production APIs and physics unchanged. |
| 2026-08-07 | 1.14.4 | feat(rate_of_closure, #4206): add validated manual reference AoA/path, targetward forward shaft lean, and tracked-reference versus registered generated-hosel shaft datums in PyQt6 and React; rotate pose, angular-rate components, and delivered face normals consistently; persist schema-v5 `manual_delivery`; export the reference-contact/reference-impact model boundary; and pin the representative Pitching Wedge decomposition in both runtimes. |
| 2026-08-07 | 1.14.3 | fix(variation, #4144): preserve trial identity when filtering finite landing coordinates so carry/lateral values from different incomplete trials cannot form fictitious points; use one paired-row contract for Python/TypeScript ellipse analysis, PyQt/React rendering, and exact plotted-count status. Clarify that the wedge kernel's 20 mm example is synthetic and separately pin the generated Pitching Wedge face-center/hosel cross-check and current UI-state limitations. |
| 2026-08-06 | 1.14.2 | feat(rate_of_closure, #4192 #4234): complete the shared spatial-target workflows in PyQt6 and React with canonical cross-tab state, versioned JSON/CSV/manifest persistence, no-run 2D/3D rendering, continuous aerial passage, surface-projected landing assessment, field-linked validation, stale-solver protection, high-DPI canvases, responsive wrapped PyQt forms, collapsible engineering detail/layer controls, and movable or hideable legends; keep aerial requests fail-closed where solver/variation objectives remain ground-only. |
@@ -3170,16 +2981,8 @@ Active development with stable core, continuous tool expansion, and web API in p
| 2026-08-06 | 1.13.13 | fix(ball-flight, #4199): migrate strategy output to v2; separate policy-fixed true-wind counterfactuals from preset-oracle regret and add failure-inclusive target-hold, miss-distance CVaR, and directional risk metrics with Python/TypeScript parity. |
| 2026-08-06 | 1.13.12 | feat(rate_of_closure, #4200): add deterministic timestamp interpolation and accessible play/pause/scrub/speed/restart/Launch/Apex/Landing controls to PyQt6 and React; preserve Matplotlib camera state with mutable markers; add a dependency-free rotatable/zoomable orthographic web canvas with a locked physical metre scale and one cancellable animation loop. |
| 2026-08-06 | 1.13.9 | feat(rate_of_closure, swing_sim, #4182 #4183 #4189): add typed reference-frame-explicit 3D D-plane geometry, face-center/contact/reference analyses, exact-versus-planar spin-loft residuals, persistent PyQt6/React engineering layers, and shaded sector exports. |
-| 2026-08-06 | 1.13.11 | feat(rate_of_closure, #4200): add deterministic timestamp interpolation and accessible play/pause/scrub/speed/restart/Launch/Apex/Landing controls to PyQt6 and React; preserve Matplotlib camera state with mutable markers; add a dependency-free rotatable/zoomable orthographic web canvas with a locked physical metre scale and one cancellable animation loop. |
-| 2026-08-10 | 1.13.11 | fix(swing-sim, d-plane, #4202): add explicit ndarray result boundaries to the private vector conversion and horizontal-projection helpers, closing the exact changed-file MyPy `no-any-return` failures without changing numerical semantics, DbC validation, frames, schemas, or UI behavior. |
-| 2026-08-10 | 1.13.10 | feat/fix(rate-of-closure, swing-sim, #4179 #4182 #4183 #4189 #4202): retain typed reference-frame-explicit 3D D-plane geometry, face-center/contact/reference analyses, exact-versus-planar spin-loft residuals, persistent PyQt6/React engineering layers, and shaded sector exports while propagating the Python 3.10 UTC repair and source-wide AST guard through the exact impact-visualization parent; extract persisted D-plane layer controls to restore the protected simulation-view module budget. |
-| 2026-08-06 | 1.13.9 | feat(rate_of_closure, swing_sim, #4182 #4183 #4189): add typed reference-frame-explicit 3D D-plane geometry, face-center/contact/reference analyses, exact-versus-planar spin-loft residuals, persistent PyQt6/React engineering layers, and shaded sector exports. |
-| 2026-08-10 | 1.13.9 | feat/fix(rate-of-closure, #4162 #4167 #4173 #4174 #4178 #4179): retain exact-event pose/twist/wrist interpolation, the versioned impact-scene contract, locked-scale PyQt6 and React views, named cameras, accessible metrics, and PNG/SVG/JSON exports while propagating the Python 3.10 UTC repair and source-wide AST guard through the exact turf-physics parent. |
-| 2026-08-10 | 1.13.8 | feat/fix(golf-club, rate-of-closure, #4166 #4167 #4173 #4174 #4178): retain the passive provenance-gated turf proxy, nine-point wedge contact wrench, strict profile persistence, convergence diagnostics, and explicit force-coupling boundary while propagating the Python 3.10 UTC repair and source-wide AST guard through the exact stacked parent. |
| 2026-08-05 | 1.13.7 | feat(rate_of_closure, #4162): add exact-event pose/twist/wrist interpolation; a versioned impact-scene contract; locked-scale orbitable wedge, shaft, ball, contact, orientation, screw-axis, and velocity-decomposition views in PyQt6 and React; named cameras, accessible metric definitions, and PNG/SVG/JSON exports. |
-| 2026-08-10 | 1.13.7 | fix(rate-of-closure, #4167 #4173 #4174): propagate the Python 3.10 UTC compatibility repair and source-wide AST guard through the impact-inspector parent into swept wedge ground clearance without rewriting the stacked child or changing its ground-contact contracts. |
| 2026-08-06 | 1.13.6 | feat(golf-club, rate_of_closure, #4166): add a passive, provenance-gated compliant turf proxy; nine-point wedge contact wrench; strict profile persistence; cancellation and refinement diagnostics; and a retained-Rate adapter with explicit force-coupling limitations. |
-| 2026-08-10 | 1.13.6 | fix(rate-of-closure, #4167 #4173): propagate the Python 3.10 UTC compatibility repair into the impact-inspector child without rewriting its history; torque-profile persistence now uses the shared compatibility export and a source-wide AST guard prevents direct, aliased, or module-attribute `datetime.UTC` regressions. |
| 2026-08-06 | 1.13.5 | refactor(gui, ci): deduplicate Rotation Converter plot helpers and extract Movement Optimizer motion helpers, restoring the protected module-size budget inherited by the stacked Rate PRs. |
| 2026-08-05 | 1.13.4 | feat(rate_of_closure, golf-club, #4158 #4160 #4163): integrate frame-explicit wedge contact/shaft kinematics into retained Rate runs; add honest impact-or-closest-approach jump controls and engineering readouts to PyQt6 and React; restore manual web angular velocity; and select the documented 30 ms square pose for flat automatic speed plateaus. |
| 2026-08-05 | 1.5.5 | fix(ci, #4155): make the Python tool-cache guard inspect `/opt/hostedtoolcache` and optionally require the interpreter's declared link library; run that stronger semantic preflight immediately before the Rust/PyO3 job provisions Python, with Linux fixture and workflow-order contracts. |
diff --git a/docs/development/RATE_OF_CLOSURE_CAMPAIGN_HANDOFF.md b/docs/development/RATE_OF_CLOSURE_CAMPAIGN_HANDOFF.md
index 9a6195ba7..e3ae4f788 100644
--- a/docs/development/RATE_OF_CLOSURE_CAMPAIGN_HANDOFF.md
+++ b/docs/development/RATE_OF_CLOSURE_CAMPAIGN_HANDOFF.md
@@ -1,5 +1,38 @@
# Rate of Closure Ball-Flight Campaign Handoff
+## 2026-08-11 PR #4342 current-parent propagation candidate
+
+- PR `#4342` retains branch `feat/4274-regional-plan-io` and base
+ `feat/4274-regional-surface-ui`. Exact current child
+ `c1f47f2ef68b3db102da5416aaac17a40f675207` is first and exact reviewed
+ local #4339 candidate `db335937afc4b587d235eb705e315f577519c5e6` is
+ second in a normal no-ff merge.
+- Child-owned canonical request import/export, bounded UTF-8, native atomic
+ save, browser-qualified download, tests, and limitations remain intact while
+ inheriting current editor, wire, regional-physics, and complete ground
+ ancestry.
+- The default shared canonical encoder still rejects floats and integers beyond
+ JavaScript's safe range. The capability-observation facade alone selects a
+ separately named extended finite-float policy that reuses the shared
+ recursion, keeps integers bounded, emits exact exponent-free `1e20` and
+ `1e21` tokens matching TypeScript, and rejects non-finite values.
+- Local qualification passes all `909` Rate-of-Closure Python tests, all `110`
+ React files / `686` tests, the complete Cargo workspace, `47` focused Python
+ compatibility/regional-I/O tests, and `12` focused React capability tests.
+ Pinned Ruff 0.14.10 check/format passes `17` changed Python files; pinned
+ MyPy 1.13 and Bandit pass `12` changed production files. TypeScript,
+ zero-warning ESLint, the 199-module Vite build, Rust format and
+ warning-denied clippy, both changed-file LOC gates, manifest/docs/blocking-
+ gate/assertion/minimum-test governance, marker scans, and diff checks pass.
+ One untouched manual-delivery UI test timed out in the first concurrent full
+ run, then passed alone and in the single complete rerun.
+- The candidate has not been rebased, retargeted, rewritten, force-pushed, or
+ published and remains `not_released`.
+- Execution/playback, result interchange, measured calibration, model-input
+ persistence, changing geometry or velocity, TypeScript/compiled regional
+ physics, downstream parity, protected exact-head evidence, review, approval,
+ dependency integration, and release remain open.
+
## 2026-08-11 PR #4339 current-parent propagation candidate
- PR `#4339` retains branch `feat/4274-regional-surface-ui` and base
@@ -29,41 +62,217 @@
physics, downstream parity, protected exact-head evidence, review, approval,
dependency integration, and release remain open.
+
+## 2026-08-11 PR #4342 append-only preservation repair
+
+Independent audit of local merge `e7fedfb18de1550eed3484ed2fc99d0baaecdca1`
+found that three older parent ancestry sections had been summarized instead of
+retained verbatim. This docs-only follow-up restores the full parent text below
+without changing production code, tests, schemas, manifest state, PR base, or
+release claims. The exact parent sections and SPEC rows are now governed by
+byte-for-byte comparison against
+`d21741e312b849a63f73cabf351a15d9de80fb94`.
+
+## 2026-08-11 PR #4335 current-parent ancestry candidate
+
+The clean dedicated `feat/4271-regional-wire-contract` worktree starts from
+exact live PR #4335 child `74a053d2d544da9f44a88007660ad28c0127f285`
+and normally merges exact newly published PR #4332 parent
+`04ccf08dd990de1cd056a3420e67772773a4be2e` as its second parent. PR #4335
+keeps base `feat/4271-regional-surface-transitions`; neither branch is rebased,
+retargeted, rewritten, force-pushed, or published by this reconciliation.
+Production physics, wire contracts, golden fixtures, numerical ordering, and
+public APIs merge byte-exactly; only SPEC, manifest, and handoff records require
+truthful reconciliation.
+
+The child retains the strict cross-runtime regional-plan request/result wire
+contract, canonical JSON/SHA-256 evidence, fail-closed parsing, and Python
+resolver adapter. The parent retains bounded coplanar regional transitions and
+the complete reconciled impact/bounce/skid/roll ancestry. Changing normals,
+height or surface-velocity discontinuities, terrain deformation, torsional-spin
+damping, roll-to-skid transitions, internal transition-ledger export, regional
+UI, compiled or TypeScript regional physics, downstream parity, protected CI,
+review, normal stack integration, and main release remain open. This local
+merge is not release evidence and requires independent review before an
+ordinary fast-forward publication.
+
+Merged-tree qualification is `132` focused Python ground tests and `9`
+focused React regional/ground-contract tests passing. Pinned Ruff 0.14.10 check
+and format pass all `45` ground Python files. Pinned MyPy 1.13 passes the exact
+two-file isolated CI boundary and all `31` production modules under the coherent
+whole-package profile that disables only redundant-cast warnings; those casts
+remain required by the isolated protected profile. Bandit reports no
+medium/high finding. Documentation governance, manifest validation/layout and
+all `8` manifest contracts, changed-production and minimum-test policies, the
+official 500-LOC PR-delta gate (`6` files, zero violations), diff checks, and
+mandatory maxima of `392` module lines, `46` function lines, and `4` parameters
+all pass.
+
+## 2026-08-11 PR #4332 current-parent ancestry candidate
+
+The clean dedicated `feat/4271-regional-surface-transitions` worktree starts
+from exact live PR #4332 child `1a48d749af508843fac2a5102f4dd56294429bda`
+and normally merges exact newly published `feat/4271-ground-skid-roll` parent
+`0ea6740965068542e9d8c7449e06ec07d88969e0` as its second parent. PR #4332
+keeps base `feat/4271-ground-skid-roll`; neither branch is rebased, retargeted,
+rewritten, force-pushed, or published by this reconciliation. The only textual
+merge conflict is the independent SPEC-version collision. SPEC 1.14.27 retains
+the regional child record after the parent's 1.14.26 entry; production physics,
+contracts, schemas, numerical ordering, and public APIs merge without conflict.
+
+The child retains bounded coplanar material overlays, explicit precedence,
+exact quadratic boundary splitting, base-edge precedence, state and energy
+continuity, strict `surface_transition` evidence, request-bound transition
+limits, and randomized piecewise-analytic coverage. The current parent retains
+its reviewed impact, bounce, skid, roll, resistance, qualified-rest, edge,
+composition, and passive-ledger behavior. Changing normals, height or
+surface-velocity discontinuities, terrain deformation, torsional-spin damping,
+roll-to-skid transitions, regional UI, compiled regional physics, downstream
+parity, protected CI, review, normal stack integration, and main release remain
+open. This local merge is not release evidence and requires independent review
+before an ordinary fast-forward publication.
+
+Merged-tree qualification is `121` focused Python ground/regional tests and
+`5` focused React ground-contract tests passing. Pinned Ruff 0.14.10 check and
+format pass all `41` ground Python files; pinned MyPy 1.13 passes all `28`
+ground production modules; and Bandit reports no medium/high finding. The
+campaign manifest validator and all `8` manifest contracts, documentation
+governance, changed-production policy, minimum test contract, both parent and
+child diff checks, and the official 500-LOC changed-file gate (`14` files,
+zero violations) pass. Production maxima are `392` lines per module, `46`
+lines per function, and `4` parameters excluding `self`/`cls`. The manifest
+now records open PR #4332 at its still-published child head and open PR #4304
+at its exact newly published parent head; neither record claims protected or
+main-release evidence.
+
+## 2026-08-11 PR #4304 current-parent ancestry candidate
+
+The clean dedicated `feat/4271-ground-skid-roll` worktree first fast-forwarded
+to exact live PR #4304 child `52d9a6a978d8e6b8b19ef92f02f265c9058b00ad`,
+then normally merged exact live `feat/4270-ground-impact-bounce` parent
+`cf6e72bad98e5f36f782254942e6895b8b71e670`. The PR base remains unchanged;
+neither branch was rebased, retargeted, rewritten, force-pushed, or published.
+The automatic merge was conflict-free. Its only child-tree change before this
+documentation reconciliation is deterministic formatting in the existing
+skid/roll regression test; production physics, contracts, schemas, numerical
+ordering, and public APIs remain unchanged.
+
+Local qualification on the merge candidate is `115` focused ground
+tests passing on CPython 3.13, pinned Ruff 0.14.10 clean across the ground
+package and tests, and pinned MyPy 1.13 clean across all `25` ground production
+modules. The manifest validator and all `8` manifest tests, documentation
+governance, exact-parent and exact-child diff checks, changed-production policy,
+the official changed-file 500-LOC budget, and mandatory production limits of
+400 lines per module, 50 lines per function, and four parameters all pass. The
+local merge is a PUBLISH candidate for independent review only; protected
+exact-head CI, approval, normal child propagation, and publication remain open.
+
+
+## 2026-08-11 PR #4342 current-parent reconciliation candidate
+
+- The clean `feat/4274-regional-plan-io` worktree normally merges exact
+ published PR #4342 child `8e1c7ccd99a7c4886c5fb9ccc7e4d94a6d7e3833`
+ with exact newly published PR #4339 parent
+ `d21741e312b849a63f73cabf351a15d9de80fb94` as its second parent.
+- PR #4342 retains base `feat/4274-regional-surface-ui`; no rebase, retarget,
+ rewrite, force-push, publication, protected-evidence, or release claim is
+ made by this reconciliation.
+- Strict regional request import/export is preserved. The child widget module
+ delegates canonical-precision controls to the parent's frozen
+ `NumberInputSpec` and three-parameter helper while retaining inclusive safe
+ number bounds and eleven-decimal presentation.
+- Merged-tree qualification is 53 focused Python/PyQt/shared-ground tests and
+ 14 focused React tests passing. Ruff, MyPy, Bandit, TypeScript, zero-warning
+ ESLint, the 199-module production build, campaign manifest and eight manifest
+ tests, documentation/tool-manifest governance, changed-Python, minimum-test,
+ exact-diff assertion, 500-LOC, parent/child diff, and whitespace gates pass.
+ Structural maxima are 396 module lines, 40 function lines, and three
+ parameters.
+- Independent review, ordinary fast-forward publication, fresh protected
+ CI/approval, dependency integration, and release remain required.
+
## 2026-08-11 PR #4339 structural helper repair candidate
-This local follow-up descends exact independently reviewed reconciliation
-candidate `eedad6d23b517eb4c99d4ba9000ff6555101099f`. Independent review found
-one publication blocker: the regional PyQt number-input helper accepted six
-parameters, above the campaign's mandatory four-parameter limit. RED-first
-tests now bind the helper's signature and all observable widget settings. A
-frozen `NumberInputSpec` validates finite positive step and finite ordered
-bounds before widget construction; the three-parameter helper preserves field
-names, values, units, ranges, increments, tooltips, and presentation order.
-
-Eight focused Python/PyQt tests and 25 focused React tests pass; the complete
-React suite passes all 108 files / 672 tests. Pinned Ruff check/format, MyPy on
-all six affected production modules, Bandit medium/high screening, TypeScript,
-zero-warning ESLint, documentation/manifest governance, changed-production,
-test-assertion, minimum-test, 500-LOC, and diff gates pass. Mandatory maxima
-are 400 module lines, 42 function lines, and three parameters. A broader
-Rate-of-Closure Python run reached the ten-minute workstation lifecycle bound
-without yielding an assertion failure; it is not counted as passing evidence.
-The monorepo-wide lane separately exposed unrelated baseline failures and
-xdist worker termination. No schema, digest, regional physics, UI behavior,
-PR base, protected evidence, or release boundary changes.
+- Parent head `d21741e312b849a63f73cabf351a15d9de80fb94` replaces the regional
+ PyQt six-parameter input helper with a frozen validated `NumberInputSpec`
+ and three-parameter helper without changing field behavior or ordering.
+- Eight focused Python/PyQt tests, 25 focused React tests, and the complete 672
+ React tests pass with Ruff, MyPy, Bandit, TypeScript, ESLint, build,
+ documentation, manifest, size, structural, and diff gates clean.
+- No schema, digest, regional physics, PR base, protected evidence, or release
+ boundary changes.
## 2026-08-11 PR #4339 current-parent ancestry candidate
-The clean `feat/4274-regional-surface-ui` worktree starts from exact published
-PR #4339 child `cbb9c0a6bdc6a50f59f7a661139b9d53e1892980` and normally merges
-exact newly published PR #4335 parent
-`9e01ccc3e891cc45907293751a192624195a77a5` as its second parent. The PR
-continues to target `feat/4271-regional-wire-contract`; neither branch is
-rebased, retargeted, rewritten, or force-pushed. Feature payloads merge without
-conflict; only SPEC, manifest, and handoff records require truthful
-reconciliation. Independent review, ordinary fast-forward publication, fresh
-protected exact-head CI, approval, dependency integration, and release remain
-open.
+- The parent worktree normally merged exact editor child
+ `cbb9c0a6bdc6a50f59f7a661139b9d53e1892980` with exact published #4335
+ parent `9e01ccc3e891cc45907293751a192624195a77a5` while retaining the
+ `feat/4271-regional-wire-contract` base.
+- UI, wire, resolver, regional physics, and ground ancestry were preserved;
+ protected exact-head review, integration, and release remained open.
+
+## 2026-08-11 PR #4342 delta-MyPy follow-up
+
+- Protected CI on exact head
+ `cffe349ac0a8054f1d168cb36684fd00bc5f8a49` rejected one redundant Boolean
+ cast in the regional atomic-write adapter.
+- The cast is removed and the typed helper's direct return is unchanged.
+ Focused persistence tests and the CI-equivalent pinned MyPy command pass.
+- No wire, validation, file, UI, or physics behavior changes. Fresh protected
+ CI/review and dependency ordering remain open.
+
+## 2026-08-11 regional request I/O protected publication
+
+- Branch `feat/4274-regional-plan-io` is published normally as draft PR
+ [#4342](https://github.com/D-sorganization/Tools/pull/4342), targeting exact
+ PR #4339 branch `feat/4274-regional-surface-ui` at parent head
+ `cbb9c0a6bdc6a50f59f7a661139b9d53e1892980`.
+- Reviewed implementation head
+ `d748e7a5ef3da5e6ce7737ff6829e0f14665fe97` includes canonical PyQt6/React
+ request import/export, safe-number parity, and bounded strict UTF-8 native
+ reads. Publication documentation commits change no runtime code.
+- Protected CI, review, #4274, dependency ordering, integration, and release
+ remain open.
+
+## 2026-08-11 bounded regional request read follow-up
+
+Independent review of local safe-number commit
+`10c394f6b1fd2927e7f3b1f96cc097cae6bfd380` found that native request import
+checked file size with `stat()` and then performed a separate unbounded text
+read. A concurrently grown or replaced file could therefore allocate beyond
+the 1 MiB wire cap before the strict parser rejected it.
+
+Native import now opens one binary handle, reads at most the wire cap plus one
+sentinel byte, rejects overflow, strictly decodes UTF-8, and only then delegates
+to the unchanged canonical v1 parser. Tests simulate content growth after the
+metadata check and reject invalid UTF-8 explicitly. The complete regional and
+atomic persistence set is 28 tests passing. This changes no schema, digest,
+physics, browser behavior, or write semantics. Static and governance evidence
+is recorded in this commit: Ruff, Ruff format, Black, focused MyPy, manifest,
+module-size, documentation-governance, and diff checks pass. The child remains
+local and unprotected.
+
+## 2026-08-11 regional request I/O safe-number follow-up
+
+Independent review of local commit `e39edf4b50b1fb9811b0032bec4758c7a08c9b74`
+found two cross-runtime representation gaps. The PyQt6 precedence spin box
+silently narrowed otherwise valid v1 integers above 1,000,000, and Python
+accepted integer-valued wire numbers above JavaScript's exact safe range.
+
+The native editor now uses an exact decimal integer entry for precedence and
+preserves every v1 value from zero through 9,007,199,254,740,991 without a
+floating-point conversion. Shared Python canonical-number and ground-record
+validation now reject magnitudes outside that same range, matching React while
+retaining all finite fractional values inside it. PyQt6 floating-point editors
+publish the same bounds. Regression coverage pins exact maximum-precedence
+open/save round-trip and matched native/browser refusal of unsafe material
+numbers. This changes no schema version, provenance algorithm, physics, or
+browser filesystem limitation. Final local evidence is 132 shared ground tests,
+21 regional editor/I/O tests, five atomic-workspace tests, 23 focused React
+tests, the whole-shell tooltip sweep, and eight manifest tests passing. Ruff,
+Ruff format, Black, focused MyPy, TypeScript, zero-warning ESLint, the 199-module
+production build, module and changed-file size budgets, documentation
+governance, and diff checks pass. The child remains local and unprotected.
## 2026-08-10 PR #4339 stale-validation invalidation follow-up
@@ -81,6 +290,43 @@ and diff checks are clean. The known polynomial-generator empty-legend warning
is unrelated. This changes no wire schema, provenance digest, physics, or
persistence boundary; fresh protected CI is still required before merge.
+## 2026-08-10 issue #4274 canonical regional request I/O local child
+
+Local branch `feat/4274-regional-plan-io` started directly from published PR
+#4339 head `a9ace5052bcd54b78f79b62d5d9ac26debedb4b1`, then fast-forwarded
+normally to corrected exact parent `cbb9c0a6bdc6a50f59f7a661139b9d53e1892980`.
+The parent's stale-validation invalidation and tooltip follow-up are preserved.
+This child has not been pushed, opened as a PR, reviewed, merged, or released.
+
+The matched Ground Surfaces editors now import and export the canonical
+`ground-regional-material-plan-request/v1` document. PyQt6 uses native Open
+and Save As dialogs plus a shared flush/fsync/atomic-replace UTF-8 writer;
+cancel is a no-op, failed reads and writes preserve the last-known-good editor
+or file, and the recent path advances only after success. React validates a
+bounded browser File before committing state and downloads exact canonical
+bytes while revoking its object URL. Browser filesystem limitations are
+explicit, and workspace persistence remains separate.
+
+Import accepts only editor producer/provider v1 evidence, the fixed target
+frame origin/downrange axis, and one to eight rows. It never relabels external
+evidence. An unchanged import round-trips the exact request and provenance;
+after any edit, validation binds a fresh draft digest. No measured calibration
+is synthesized and neither path executes physics.
+
+RED-first coverage now includes exact-byte round-trip, native cancel and
+atomic rollback, corruption, duplicate keys, oversize input, unsupported
+producer/axis qualification, stale-provenance rebinding, transactional PyQt6
+population, browser rollback, URL cleanup, and pre-allocation size rejection.
+Focused evidence is 25 Python/PyQt tests and 12 React tests passing. With
+adjacent wire and manifest coverage, 44 Python and 16 React tests pass.
+Focused MyPy, Ruff, TypeScript, zero-warning ESLint, the 199-module production
+build, release-manifest validation, and module budgets are clean.
+
+Issue #4274 remains open. Measured calibration, workspace model-input
+persistence, execution/playback, result interchange, visualization, changing
+geometry, compiled regional physics, downstream parity, protected CI/review,
+integration of this child into the protected stack, and release remain explicit
+gaps.
## 2026-08-10 issue #4274 matched regional surface editor local child
Local branch `feat/4274-regional-surface-ui` started from published PR #4335
@@ -125,63 +371,7 @@ terrain/interval visualization, TypeScript or compiled regional physics,
UpstreamDrift parity, protected CI/review, parent integration, and main release
remain open.
-## 2026-08-11 Current regional-surface parent propagated into regional wire
-
-- Open draft PR `#4335` retains branch `feat/4271-regional-wire-contract` and
- base `feat/4271-regional-surface-transitions`. Exact remote regional-wire
- child `9e01ccc3e891cc45907293751a192624195a77a5` is merged first and exact current
- regional-surface parent `5ac3c1f233de30dd42eeac57073cbdb149bde652`
- second by an ordinary no-ff merge.
-- Strict Python/TypeScript regional-plan schemas, canonical JSON/SHA-256
- fixture evidence, fail-closed parsing, Python resolver binding, tests,
- contracts, limitations, and both append-only histories remain intact.
-- Focused local qualification passes all `132` Python ground/regional-wire
- tests, `9` focused React regional/ground-contract tests, and all `137`
- `tools-core` Rust tests. TypeScript, zero-warning ESLint, the 190-module Vite
- build, Rust format and warning-denied clippy, pinned Ruff 0.14.10 across six
- changed Python files, pinned MyPy 1.13 and Bandit medium/high across four
- production files, the 500-LOC changed-file gate, manifest parsing plus eight
- contracts, documentation governance, exact wire-tree preservation,
- history/marker, and diff checks pass.
-- The candidate is unpublished and `not_released`; changing geometry or
- velocity, internal transition-ledger export, regional UI, compiled or
- TypeScript regional physics, UpstreamDrift parity, protected exact-head CI,
- review, approval, dependency integration, and release remain open.
-
-## 2026-08-11 PR #4335 current-parent ancestry candidate
-The clean dedicated `feat/4271-regional-wire-contract` worktree starts from
-exact live PR #4335 child `74a053d2d544da9f44a88007660ad28c0127f285`
-and normally merges exact newly published PR #4332 parent
-`04ccf08dd990de1cd056a3420e67772773a4be2e` as its second parent. PR #4335
-keeps base `feat/4271-regional-surface-transitions`; neither branch is rebased,
-retargeted, rewritten, force-pushed, or published by this reconciliation.
-Production physics, wire contracts, golden fixtures, numerical ordering, and
-public APIs merge byte-exactly; only SPEC, manifest, and handoff records require
-truthful reconciliation.
-
-The child retains the strict cross-runtime regional-plan request/result wire
-contract, canonical JSON/SHA-256 evidence, fail-closed parsing, and Python
-resolver adapter. The parent retains bounded coplanar regional transitions and
-the complete reconciled impact/bounce/skid/roll ancestry. Changing normals,
-height or surface-velocity discontinuities, terrain deformation, torsional-spin
-damping, roll-to-skid transitions, internal transition-ledger export, regional
-UI, compiled or TypeScript regional physics, downstream parity, protected CI,
-review, normal stack integration, and main release remain open. This local
-merge is not release evidence and requires independent review before an
-ordinary fast-forward publication.
-
-Merged-tree qualification is `132` focused Python ground tests and `9`
-focused React regional/ground-contract tests passing. Pinned Ruff 0.14.10 check
-and format pass all `45` ground Python files. Pinned MyPy 1.13 passes the exact
-two-file isolated CI boundary and all `31` production modules under the coherent
-whole-package profile that disables only redundant-cast warnings; those casts
-remain required by the isolated protected profile. Bandit reports no
-medium/high finding. Documentation governance, manifest validation/layout and
-all `8` manifest contracts, changed-production and minimum-test policies, the
-official 500-LOC PR-delta gate (`6` files, zero violations), diff checks, and
-mandatory maxima of `392` module lines, `46` function lines, and `4` parameters
-all pass.
## 2026-08-10 PR #4335 isolated-MyPy return typing
@@ -231,66 +421,8 @@ This child remains `not_released`. Protected CI, independent review, normal
stack integration, UI, TypeScript/Rust/PyO3/WASM regional physics, changing
normals/heights/velocities, internal transition-ledger wire export,
UpstreamDrift parity, and main release remain open.
-## 2026-08-11 Current skid/roll parent propagated into regional surfaces
-
-- Open draft PR `#4332` retains branch
- `feat/4271-regional-surface-transitions` and base
- `feat/4271-ground-skid-roll`. Exact remote regional-surface child
- `04ccf08dd990de1cd056a3420e67772773a4be2e` is merged first and exact current
- skid/roll parent `3f861c1faaa7455faee92eaa7f813174667208e0`
- second by an ordinary no-ff merge.
-- Bounded coplanar material overlays, precedence, exact boundary splitting,
- transition evidence, continuity, regional production, tests, fixtures,
- contracts, limitations, and both append-only histories remain intact.
-- Focused local qualification passes all `121` Python ground/regional tests,
- `20` focused React ground-contract/transfer tests, and all `137` `tools-core`
- Rust tests. TypeScript, zero-warning ESLint, the 189-module Vite build, Rust
- format and warning-denied clippy, pinned Ruff 0.14.10 across 14 changed
- Python files, pinned MyPy 1.13 and Bandit medium/high across 12 production
- files, the 500-LOC changed-file gate, manifest parsing plus eight contracts,
- documentation governance, exact child-tree preservation, history/marker,
- and diff checks pass.
-- The candidate is unpublished and `not_released`; changing normals,
- discontinuous geometry or surface velocity, regional UI, compiled regional
- physics, UpstreamDrift parity, protected exact-head CI, review, approval,
- dependency integration, and release remain open.
-
-## 2026-08-11 PR #4332 current-parent ancestry candidate
-
-The clean dedicated `feat/4271-regional-surface-transitions` worktree starts
-from exact live PR #4332 child `1a48d749af508843fac2a5102f4dd56294429bda`
-and normally merges exact newly published `feat/4271-ground-skid-roll` parent
-`0ea6740965068542e9d8c7449e06ec07d88969e0` as its second parent. PR #4332
-keeps base `feat/4271-ground-skid-roll`; neither branch is rebased, retargeted,
-rewritten, force-pushed, or published by this reconciliation. The only textual
-merge conflict is the independent SPEC-version collision. SPEC 1.14.27 retains
-the regional child record after the parent's 1.14.26 entry; production physics,
-contracts, schemas, numerical ordering, and public APIs merge without conflict.
-The child retains bounded coplanar material overlays, explicit precedence,
-exact quadratic boundary splitting, base-edge precedence, state and energy
-continuity, strict `surface_transition` evidence, request-bound transition
-limits, and randomized piecewise-analytic coverage. The current parent retains
-its reviewed impact, bounce, skid, roll, resistance, qualified-rest, edge,
-composition, and passive-ledger behavior. Changing normals, height or
-surface-velocity discontinuities, terrain deformation, torsional-spin damping,
-roll-to-skid transitions, regional UI, compiled regional physics, downstream
-parity, protected CI, review, normal stack integration, and main release remain
-open. This local merge is not release evidence and requires independent review
-before an ordinary fast-forward publication.
-Merged-tree qualification is `121` focused Python ground/regional tests and
-`5` focused React ground-contract tests passing. Pinned Ruff 0.14.10 check and
-format pass all `41` ground Python files; pinned MyPy 1.13 passes all `28`
-ground production modules; and Bandit reports no medium/high finding. The
-campaign manifest validator and all `8` manifest contracts, documentation
-governance, changed-production policy, minimum test contract, both parent and
-child diff checks, and the official 500-LOC changed-file gate (`14` files,
-zero violations) pass. Production maxima are `392` lines per module, `46`
-lines per function, and `4` parameters excluding `self`/`cls`. The manifest
-now records open PR #4332 at its still-published child head and open PR #4304
-at its exact newly published parent head; neither record claims protected or
-main-release evidence.
## 2026-08-10 issue #4271 coplanar regional-material local child
Local branch `feat/4271-regional-surface-transitions` starts from exact current
@@ -327,555 +459,10 @@ regional physics, UpstreamDrift parity, protected CI, review, normal stack
integration, and main release remain open. Region plans and from/to identity
records are execution-scoped non-wire data in this child.
-## 2026-08-11 Current impact/bounce parent propagated into skid/roll
-
-- Open draft PR `#4304` retains branch `feat/4271-ground-skid-roll` and base
- `feat/4270-ground-impact-bounce`. Exact remote skid/roll child
- `0ea6740965068542e9d8c7449e06ec07d88969e0` is merged first and exact current
- impact/bounce parent `62beb3e1aa951645fd556a53f9cbae4bb46c47e5`
- second by an ordinary no-ff merge.
-- The child-owned arbitrary-plane skid, static-feasible pure roll, rolling
- resistance, qualified rest, edge localization, strict result composition,
- passive ledgers, tests, fixture, and limitations remain intact with both
- append-only handoff/SPEC histories.
-- Local verification passes `154` focused ground/flight tests, all eight
- campaign-manifest tests, and all `137` `tools-core` Rust tests. Pinned Ruff
- 0.14.10 covers 18 PR-delta Python files; pinned MyPy 1.13 and Bandit
- medium/high cover 12 production files. Rust format/clippy, manifest, docs,
- exact child-tree, history/marker, and diff gates pass.
-- This remains a local `not_released` candidate. Regional/changing-normal
- surfaces, deformation, torsional damping, roll-to-skid transitions, UI,
- compiled physics, publication, protected exact-head CI, review, approval,
- downstream integration, and release remain open.
-
-## 2026-08-10 PR #4302 corrected-flight-transfer propagation
-
-Draft PR #4302 remains on `feat/4270-ground-impact-bounce` with unchanged base
-`feat/4269-flight-ground-transfer`. Exact corrected #4288 parent
-`247215422a6d4b677552955b4923bc609a553259` is incorporated by the normal merge
-containing this handoff. The child preserves its passive restitution/Coulomb
-sphere-plane impulse, deterministic repeated ballistic hops, exact physical
-contact, capture-to-skid handoff, cancellation/failure semantics, and airborne
-segment evidence while inheriting the corrected transfer ancestry, deterministic
-workspace timestamps, and canonical `swing_sim` import identity. No branch was
-rebased, retargeted, rewritten, or force-pushed.
-
-The child implementation is the scoped Python reference prefix from
-`docs/specs/GROUND_IMPACT_BOUNCE.md`: it includes full spin, moving-boundary
-accounting, exact first contact, bounded repeat-hop execution, typed airborne
-segments, and a shared golden fixture. It remains partial and `not_released`.
-Issue #4271 retains skid, roll, rest, total distance, and final
-`GroundSimulationResult`; terrain deformation, UI execution, TypeScript bounce
-physics, compiled Rust/PyO3/WASM bounce parity, and UpstreamDrift adapters remain
-excluded. Protected CI, independent review, and dependency-ordered collapse
-remain separate release gates.
-
-Merged-tree validation is `987` Python tests, `106` React files / `661` tests,
-and the complete `tools-core` Rust suite at `137` tests (`111` unit, `20`
-transfer, `6` wire). The affected cross-version suite is also `146` tests on
-real CPython 3.10.20. The 189-module Vite production build, TypeScript,
-zero-warning ESLint, Ruff check/format across 90 files, pinned mypy 1.13 across
-all 17 ground and nine transfer production modules, Rust workspace format plus
-warning-denied `tools-core` clippy, campaign-manifest validator plus eight
-contracts, documentation governance, 11-file 500-LOC budget, marker scan, and
-diff checks are clean. Hosted checks and review apply to the new exact merge
-head only.
-
-
-## 2026-08-10 PR #4288 corrected-ground propagation
-
-Draft PR #4288 remains on `feat/4269-flight-ground-transfer` with unchanged
-base `feat/4268-ground-contract`. Exact corrected #4285 parent
-`788aa547651a3685a363ea401824a5d81477bafb` is incorporated by the normal merge
-containing this handoff. The child retains its qualified signed terminal state,
-physical sphere/terrain contact brackets, strict provenance, and cross-runtime
-Python/TypeScript/Rust/PyO3/WASM contracts while inheriting deterministic
-workspace timestamps and canonical `swing_sim` import identity. No branch was
-rebased, retargeted, rewritten, or force-pushed.
-
-This propagation does not add bounce, skid, roll, terrain response, total
-distance, or UI execution. Protected CI, independent review, and normal
-dependency-ordered collapse remain separate release gates.
-
-Merged-tree validation is `951` Python tests, `106` React files / `661` tests,
-and `26` focused Rust transfer/wire tests. The affected cross-version suite is
-also `110` tests on real CPython 3.10.20. The 189-module Vite production build,
-TypeScript, zero-warning ESLint, Ruff check/format across 82 files, pinned mypy
-1.13 across the six-file transfer and 13-file parent production namespaces,
-Rust workspace format plus warning-denied `tools-core` clippy, campaign-manifest
-validator plus eight contracts, documentation governance, 13-file 500-LOC
-budget, marker scan, and diff checks are clean. Hosted checks and review apply
-to the new exact merge head only.
-
-
-## 2026-08-10 PR #4282 workspace timestamp propagation
-
-Exact corrected #4281 parent
-`cf52529b1e68479321bb93b1be3d59c77f782008` is incorporated into
-`feat/4199-wind-workflow` by the normal merge containing this handoff. PR #4282
-keeps base `feat/4199-wind-scalar-adapter`; neither branch was rebased,
-retargeted, rewritten, or force-pushed. The consolidated wind/capability
-workflow inherits the deterministic Python 3.10-3.12 UTC parser, variation
-export, and scalar-ensemble history without changing its own behavior.
-
-The monotonic SPEC assigns 1.14.10 to compatibility, 1.14.11 to variation,
-1.14.12 to the scalar adapter, and 1.14.13 to this workflow carrier. The
-reconciled tree passes `924` combined Python tests, `28` direct compatibility
-tests on real CPython 3.10.20, and `104` React files / `642` tests. The Vite
-production build, TypeScript, zero-warning ESLint, Ruff, format, pinned mypy
-1.13, campaign-manifest validator and its eight contracts, documentation
-governance, source-size, conflict-marker, and diff gates are clean. Protected
-CI, review, and downstream propagation remain open.
-
-
-## 2026-08-10 PR #4280 workspace timestamp propagation
-
-Exact parent `05383d333b6fd87eaf5e37305476f50b505c2c2e` is incorporated into
-`feat/4144-variation-export-continuation` through the normal merge containing
-this handoff. PR #4280 keeps base `feat/4218-toolstrip-workspace`; neither
-branch was rebased, retargeted, force-pushed, or rewritten. The reconciled tree
-retains all variation export/accessibility behavior and adds the strict
-cross-version workspace timestamp parser.
-
-SPEC 1.14.10 remains the parent compatibility entry and SPEC 1.14.11 becomes
-the child variation entry. The reconciled tree passes `778` Rate tests, `27`
-real-Python-3.10.20 compatibility tests, `1 file / 8` focused React tests,
-TypeScript, focused zero-warning ESLint, Ruff, format, and pinned mypy 1.13.
-Documentation, size, and diff gates must remain clean in the merge commit.
-Protected CI, review, and later propagation remain open.
-
-
-## 2026-08-09 PR #4280 variation-export propagation
-
-Draft #4280 remains based on `feat/4218-toolstrip-workspace` and includes exact
-corrected parent `3f67ed466fefc8991db9c4409f921f25e1c37142` through a normal
-merge. The child retains complete selected-scatter-axis CSV export parity,
-typed unavailable rows, PyQt accessible raw tables, and the focused
-table/scatter/matrix split.
-
-
-## 2026-08-10 PR #4279 fractional timestamp compatibility
-
-Descendant PR #4281's exact-head Python 3.10 lane failed the workspace instant
-ordering regression because that interpreter rejects one-, two-, four-, and
-five-digit fractional seconds before comparison. The correction belongs on
-the earliest carrier, PR #4279: enforce one anchored UTC grammar, parse zero
-through six fractional digits consistently, and reject precision beyond
-microseconds instead of allowing newer interpreters to truncate it.
-Persisted JSON remains unchanged and UTC-only validation stays authoritative.
-
-Local evidence is `778 passed` for the full Rate suite, `45 passed` for the
-workspace/compatibility suites, and `27 passed` for the direct compatibility
-suite on CPython 3.10.20. Ruff, format, pinned mypy 1.13, docs governance, and
-the 400-line budget pass. Publication is not completion: verify the exact
-remote head/base, push normally, then propagate in stack order through #4280,
-#4281, #4282, and every later descendant that carries the workspace.
-
-
-## 2026-08-09 Capability results stabilization
-
-The isolated `feat/4201-capability-results-diagnostics` continuation is based
-on exact wind-workflow carrier head `18fe89201`. It closes two audit findings
-without changing the optimizer or physics: both clients expose every ranked
-diagnostic and parameter unit, both provide result CSV plus versioned result
-JSON, and React scalar scatters now carry numeric scales and cohort legends.
-Raw observation exports remain lossless and distinct. This is feature-stack
-implementation evidence only; #4197/#4201 remain open through integration,
-hosted CI, review, downstream parity, and release to `main`.
-
-Local evidence: 813 Rate Python/PyQt tests and 104 React files / 628 tests,
-Ruff check/format, targeted mypy for the new export and tab modules, TypeScript,
-zero-warning ESLint, and the 188-module Vite production build passed. The
-pre-existing mypy 1.19.1/Python 3.13 internal serialization assertion on
-`capability_results.py` reproduces unchanged at carrier `18fe89201`.
-
-
-## 2026-08-09 Web-release stability continuation
-
-Local branch `feat/4201-web-release-stability` is based exactly on campaign
-carrier `18fe89201`. It fixes direct-path execution of
-`src/rate_of_closure/launch_web.py`, adds a subprocess delegation smoke
-contract, and reconciles the supported release boundary to the files that
-exist: static Vite web output plus PyQt6/PyInstaller desktop output. Rate has
-no `src-tauri` project, so its stale Tauri scripts, CLI dependency, lockfile
-entries, and current documentation claims were removed instead of inventing an
-unqualified wrapper.
-
-The load-sensitive `FlightExplorerPanel` assertion now explicitly settles the
-real lazy Wind Strategy import inside React `act`; it does not extend a timeout
-or replace the child component with a mock. This is test synchronization only,
-not a UI or physics change. The branch must remain local until reviewed and
-folded into the established campaign carrier; no PR, push, or merge belongs to
-this handoff slice.
-
-Exact local evidence: 813 Rate Python/PyQt tests passed with 15 existing
-warnings; 9 launcher/registration tests passed; 102 React files / 624 tests
-passed; and five sequential focused Flight Explorer runs passed 25/25 tests.
-TypeScript type-check, zero-warning ESLint, the 187-module static build,
-focused Ruff check/format, targeted mypy, package installation/audit, and diff
-checks pass. `tests/test_dry_compliance.py` retains two unrelated baseline
-failures for the Movement Optimizer and Optimizer GUI PyQt launchers.
-
-
-## 2026-08-09 Machine-readable campaign authority
-
-`docs/release/rate_of_closure_campaign.v1.json` is now the canonical current
-state for the primary Rate, impact, flight, variation, club-builder, wedge,
-toolstrip, design-quality, parity, and ground programs. Its normalized carrier
-and evidence tables replace status inference from the chronological entries
-below. `scripts/rate_campaign_manifest.py` supplies strict Pydantic validation
-and a generated JSON Schema; it rejects missing programs, unresolved evidence,
-placeholders, malformed SHAs, and contradictory release claims.
-
-The authority records the current campaign as **not released**. Capability PRs
-#4294, #4289, and #4283 are merged into feature parent #4282, but those were not
-protected `main` merges. Current carrier head `18fe89201` contains the hermetic
-`swing_core` parity-lane correction and its focused workflow regression; a
-fresh hosted parity run, top-down stack propagation, #4133 reconciliation,
-#4119 current-main conflict resolution, protected checks, installed-package
-evidence, and UpstreamDrift parity are still required.
-
-Maintain the JSON authority and the current-state handoffs in the same commit
-whenever a carrier SHA, test result, limitation, supported surface, or release
-stage changes. Historical detail below remains useful provenance but must not
-override a contradictory validated manifest record.
-
-The four reviewed stabilization slices are composed on implementation head
-`2c1a77baa`: strict workflow parsing/signed editing, complete capability
-diagnostics and result exports, static-web entrypoint/package truth, and this
-manifest authority. Combined local evidence is 828 Rate Python/PyQt tests and
-104 React files / 642 tests, TypeScript, zero-warning ESLint, the 188-module
-Vite build, Ruff, targeted mypy, deterministic manifest/schema validation, and
-nine manifest/parity contracts. This remains local evidence; #4282 still needs
-a normal push, exact-head hosted CI, review, and dependency-ordered release.
-
-The first exact-head hosted quality gate (`31340032608`) passed checkout,
-dependency installation, Ruff, and formatting, then failed mypy 1.13 because
-`--follow-imports=skip` exposed Pydantic and Qt boundary returns as `Any`. The
-loader now casts the validated model and the playback adapter converts elapsed
-milliseconds to a concrete `float`; these are static typing fixes, not schema
-or runtime behavior changes. The exact Python 3.12/mypy 1.13 command passes all
-54 delta files; Ruff, 62 focused regression tests, and eight campaign-manifest
-tests pass locally.
-
-
-## 2026-08-11 Current flight-transfer parent propagated into ground impact
-
-- Open draft PR `#4302` retains branch `feat/4270-ground-impact-bounce` and base
- `feat/4269-flight-ground-transfer`. Exact remote bounce child
- `cf6e72bad98e5f36f782254942e6895b8b71e670` is merged first and exact current
- transfer parent `c39297d37a17d5d8d3520ed62c5563cdcc609cab` second by an
- ordinary no-ff merge.
-- Passive sphere-plane impact, restitution/friction, deterministic repeated
- bounce, exact contact, capture-to-skid handoff, cancellation/failure evidence,
- and the full current transfer ancestry are retained with both append-only
- handoff/SPEC histories.
-- Three inherited PR-delta Python files receive AST-equivalent pinned Ruff
- 0.14.10 normalization; analysis, persistence, and contract assertion behavior
- are unchanged.
-- Local verification passes `1129` Rate/ground/flight Python tests, `25`
- focused React transfer tests, and all `137` `tools-core` Rust tests, plus
- TypeScript, zero-warning ESLint, the 189-module build, Rust format/clippy,
- pinned Ruff 0.14.10, pinned MyPy 1.13, Bandit medium/high, manifest parsing,
- history preservation, and diff checks.
-- This remains a local `not_released` candidate. Skid, roll, rest, total
- distance, final ground results, UI, TypeScript bounce physics, compiled bounce
- runtimes, publication, protected exact-head CI, review, approval, dependency
- integration, and release remain open.
-
-## 2026-08-10 PR #4285 workspace timestamp propagation
-
-Draft PR #4285 remains on `feat/4268-ground-contract` with unchanged base
-`feat/4197-capability-observer`. Exact corrected #4282 carrier
-`5f77af4add23547a21cc3fabce98ae9ad4260427` is incorporated through the normal
-merge containing this handoff. The strict ground-contract child retains its
-schemas, canonical fixture, migrations, legacy-result adapter, declared
-dependency, and pinned typing repairs while inheriting the deterministic Python
-3.10-3.12 UTC parser and the corrected variation, scalar, wind, capability, and
-campaign-release ancestry. No branch was rebased, retargeted, rewritten, or
-force-pushed.
-
-The preceding exact-head Python 3.12 job then exposed an import-order defect,
-not a physics failure: embedded `src.shared.python.swing_sim` test packages and
-canonical `shared.python.swing_sim` imports could become distinct module trees,
-so ground and impact contract collection failed. The shared alias registry now
-coalesces `swing_sim`; a subprocess identity regression was RED before the fix
-and passes with both affected public-API suites afterward. The contemporaneous
-file-size run was cancelled during checkout before its budget step, so no size
-violation was reported.
-
-Merged-tree evidence is `915` Rate/ground/impact Python tests, the full
-`12`-test shared-alias architecture suite, `28` focused tests on CPython 3.12,
-`28` direct compatibility tests on real CPython 3.10.20, and `104` React files /
-`642` tests. The 188-module Vite build, TypeScript, zero-warning ESLint, Ruff,
-format, pinned mypy 1.13, campaign-manifest validator plus eight contracts,
-documentation governance, the 44-file 500-LOC budget, marker scan, and diff
-checks are clean. Hosted CI and review still apply only to the new exact head.
-
-This is ancestry reconciliation, not new landing physics. Qualified bounce,
-skid, roll, terrain profiles, total distance, UI execution, Rust/WASM parity,
-protected CI, review, and release remain open. PR #4288 must normally merge the
-resulting exact #4285 head before its transfer behavior is evaluated as a
-descendant of the corrected carrier.
-
-## 2026-08-11 Current strict-ground parent propagated into flight transfer
-
-- Open draft PR `#4288` retains branch `feat/4269-flight-ground-transfer` and
- base `feat/4268-ground-contract`. Exact remote child
- `df716ac740beb9d47dced66f867dc3dde1fa5367` is merged first and exact current
- parent `584e4e53a7990053a346938c4e45538786887ec7` second by an ordinary
- no-ff merge.
-- The child-owned Python/TypeScript/Rust/PyO3/WASM transfer, physical contact
- evidence, production, tests, fixtures, and limitations remain intact. Only
- append-only handoff/SPEC conflicts require aggregation, preserving every dated
- record from both parents.
-- Focused verification passes 85 Python contract/transfer tests, 25 React tests,
- and 137 Rust library and transfer/wire tests. Pinned Ruff 0.14.10 covers 13
- PR-delta Python files, pinned MyPy 1.13 covers nine production files, and
- Bandit reports no medium/high findings. TypeScript, exact-delta ESLint, the
- 189-module build, Rust format, docs, strict manifest, diff, exact transfer-tree,
- and both-parent preservation checks pass.
-- This bounded local audit does not authorize publication or release. Protected
- exact-head CI, review, approval, and release remain open.
-
-## 2026-08-11 PR #4288 append-only history preservation repair
-
-This documentation-only follow-up to exact local candidate
-`1eb4188ff1a87a3d8e9a55aeca68194ca04e0bb4` restores every omitted #4285
-parent handoff section and specification history row verbatim. It repairs one
-interleaved rate-of-closure paragraph without changing implementation, tests,
-schemas, manifest data, merge topology, or #4288's
-`feat/4268-ground-contract` base. The repaired candidate remains local pending
-independent review, ordinary publication, fresh protected CI, approval,
-dependency integration, and release.
-
-## 2026-08-11 PR #4288 current-ground-parent ancestry candidate
-
-Draft PR #4288 remains on `feat/4269-flight-ground-transfer` with unchanged
-base `feat/4268-ground-contract`. Exact published child
-`afb1bdcfc6701caaf1f7bc3497a6a37dd9698c14` normally merges exact newly
-published #4285 parent `e09ab96280cab363b36bd0e7db4a3cd064dc2527`
-second. The child keeps its bounded TypeScript integrator and qualified
-cross-runtime terminal-state/contact transfer; the parent contributes the
-current strict-ground, wind/capability, split-kinetics, plotting-catalog, and
-format ancestry. Seven child-owned Python files receive pinned Ruff 0.14.10
-normalization with no AST change, and the child TypeScript facade is retained
-with standard line endings. No branch is rebased, retargeted, rewritten, force-pushed, or
-released. Independent review, ordinary publication, fresh protected exact-head
-CI, approval, dependency integration, and release remain required.
-
-## 2026-08-11 Current capability carrier propagated into ground contract
-
-- Open draft PR `#4285` retains `feat/4268-ground-contract` over
- `feat/4197-capability-observer`. Exact remote child
- `e09ab96280cab363b36bd0e7db4a3cd064dc2527` is merged first and exact current
- capability-observer carrier `d0b827667e61f0583e1dad0b3cbbca6819624d3c`
- second by an ordinary no-ff merge.
-- The merge preserves the complete strict flight-to-ground contract tree and
- all current wind/capability ancestry. Only append-only handoff/SPEC documents
- conflict; every dated record from both histories is retained.
-- Focused validation passes 214 Python/PyQt tests. Pinned Ruff 0.14.10 covers
- all 27 PR-delta Python files, pinned MyPy 1.13 covers all 20 production files,
- and Bandit reports no medium/high findings. Docs, strict manifest, diff, exact
- ground-tree, and append-only preservation checks pass.
-- This local candidate is not published or released. Protected exact-head CI,
- review, approval, and normal descendant propagation into #4288 remain open.
-
-## 2026-08-11 Current workflow/base ancestry reconciled into ground contract
-
-- Draft PR `#4285` remains on `feat/4268-ground-contract`, based on
- `feat/4197-capability-observer`. Exact remote child
- `7a38b9838d743e051a6900620c4d6e754582aa89` is the first parent and exact
- published base/workflow head
- `b2baf6ef615b0d756a86ac4ca7eef2fc583210ee` is merged second.
-- GitHub ancestry established that the published base contains exact merged
- #4283 head `9bbb98e16e435a0d4c74153b909f2ebfefbbce7a` before this reconciliation.
- No branch is rebased, retargeted, force-pushed, or rewritten.
-- Ground-contract behavior is preserved. The only source conflict is an
- obsolete formatting-only edit to monolithic kinetics and resolves to the
- parent's validated split facade; all append-only documentation histories
- remain present.
-- The retained child `float` narrowing selects the plotting catalog as changed.
- Its literal registry is split by scalar and series responsibility behind the
- unchanged public catalog facade, restoring the strict 400/50/4 production
- budgets while preserving registry order and behavior.
-- Complete local evidence is 1,539 passed with one optional Rust-wheel skip for
- Rate/shared-swing Python, 106 React files / 648 tests plus type-check, lint,
- and the 188-module build, and 12 Rust tests. The focused contract/parity/
- kinetics/wind/manifest suite passes 146 tests and the catalog/plot regression
- suite passes 57 tests.
-- This local candidate is not published or released. Independent exact-head
- review, ordinary publication, fresh protected CI, required approval, and a
- later normal descendant merge into #4288 remain release gates.
-
-## 2026-08-11 merged capability-observer carrier receives current #4282
-
-- Merged PR `#4283` used `feat/4197-capability-observer`, which remains the
- current base of open draft PR `#4285`. Exact remote/local carrier child
- `b2baf6ef615b0d756a86ac4ca7eef2fc583210ee` is the first parent and exact
- published #4282 head `3faf9e9493c9ba37168d9f65ab10cafeedc2a72f`
- is the second parent of this normal local no-ff merge.
-- The carrier is already an ancestor of #4282, so all implementation merges
- without conflict. The exact #4282 responsive wind/capability/manifest tree and
- the complete merged capability-observer history are preserved; only this
- current carrier handoff and SPEC release row are intentionally added.
-- Focused validation is green: 86 Python/PyQt capability, wind, and campaign-
- manifest tests and all 86 tests in 12 focused React capability/wind suites
- pass. React type-check, zero-warning lint, and the production build pass. Docs
- governance, strict campaign-manifest validation, and exact-parent diff hygiene
- pass. The exact #4282 delta is documentation-only, so changed-Python
- Ruff/MyPy/Bandit gates are not applicable.
-- This bounded audit does not authorize publication. Independent review,
- ordinary branch publication, protected exact-head CI,
- and later #4285 propagation remain open.
-
-## 2026-08-11 current scalar-adapter propagation into wind workflow PR #4282
-
-- PR `#4282` remains on `feat/4199-wind-workflow`, based on
- `feat/4199-wind-scalar-adapter`. Exact published child
- `b2baf6ef615b0d756a86ac4ca7eef2fc583210ee` is the first parent and exact
- newly published scalar-adapter head
- `9321c1d2e091b8c7e5a4a83aa9ad726290e7fb5a` is the second parent of this
- normal local merge.
-- Production and test paths merge automatically. Responsive PyQt6/React wind
- execution, progress/cancellation, controls, scatter, persistence/export,
- consolidated capability workflow, and strict campaign release authority
- remain authoritative while inheriting the current scalar-adapter, variation,
- workspace/toolstrip, launch-monitor/D-plane, split-kinetics, and Qt repairs.
- Only append-only handoffs and SPEC conflict textually; both histories remain.
-- Focused pre-commit regression is green: 94 Python/PyQt wind, responsive-
- layout, navigation, playback, and manifest tests pass, as do all 44 tests in
- eight focused React wind/responsive suites. Docs governance and strict
- campaign-manifest generation/validation also pass.
-- Exact post-commit PR-delta gates are also green: pinned Ruff 0.14.10 checks
- and formats 57 changed Python files, pinned MyPy 1.13.0 accepts 38 production
- files, and pinned Bandit 1.7.7 finds no medium/high issues in 37 scanned source
- files. The 500-LOC budget, changed-Python policy, minimum-test contract,
- changed-test assertions, diff hygiene, React type-check/lint, and production
- web build all pass.
-- No issue or epic is completed by this propagation. Independent review,
- normal publication,
- protected exact-head CI, unresolved-thread checks, dependency integration,
- and release remain open.
-
-## 2026-08-11 Exact #4281 parent propagation into PR #4282
-
-- Draft PR `#4282` retains branch `feat/4199-wind-workflow` and base
- `feat/4199-wind-scalar-adapter`. Exact remote child
- `29e15d6ff631f7f30afcc745be783f2e716d7dcf` normally merges exact published
- parent `a7dce5f89b483303938f518b74b4028a1c68ba81` second without rewriting either
- history or the dependency stack.
-- Responsive PyQt6/React wind execution, progress/cancellation, controls,
- scatter, persistence/export, and the consolidated capability stack remain
- authoritative. The parent contributes its split kinetics facade, Ground/Tee
- parity, and strict 252-line public/213-line private scalar-adapter design.
-- The obsolete formatting-only child edit to monolithic kinetics resolves to
- the parent facade. All documentation history remains present. Seven
- child-owned Ruff-format failures remain the only known current-head code
- formatting correction. The skipped-import MyPy profile additionally replaces
- one now-unused cache-return ignore with an explicit typed cast that preserves
- the cached object and runtime behavior. Independent review and protected CI
- remain required.
-- Local evidence is 74 focused Python/PyQt wind, kinetics, and Ground/Tee
- tests; 29 focused React tests; and 8 campaign-manifest tests. TypeScript,
- focused zero-warning ESLint, Ruff check/format, pinned MyPy 1.13, Bandit's
- medium/high threshold, strict wind module/signature/function budgets,
- manifest, documentation, policy, SPEC, and diff gates pass.
-
-## 2026-08-11 current variation propagation into wind scalar PR #4281
-
-- PR `#4281` remains on `feat/4199-wind-scalar-adapter`, based on
- `feat/4144-variation-export-continuation`. Exact published child
- `a7dce5f89b483303938f518b74b4028a1c68ba81` is the first parent and exact
- newly published variation head `e6c7460a01082631565fb9ed48aa32538bd7772c`
- is the second parent of this normal local merge.
-- Production and test paths merge automatically. Matching Python/TypeScript
- `scalar-ensemble/v1` provenance, availability, deterministic-scenario,
- wind-strategy adapter, and strict module-budget behavior remain authoritative
- while inheriting current variation visualization/export, workspace/toolstrip,
- launch-monitor/D-plane ancestry, split kinetics, and Qt typing repairs. Only
- the three canonical handoffs and SPEC conflict textually; both append-only
- histories are retained.
-- Focused pre-commit regression is green: 77 Python wind/variation tests and all
- 20 tests in the five focused React wind/variation suites pass. Exact
- post-commit PR-delta gates are also green: pinned Ruff 0.14.10 checks/formats
- five changed Python files, pinned MyPy 1.13.0 accepts three production files,
- and pinned Bandit 1.7.7 finds no issues in those three files. Both 500- and
- strict 400-LOC budgets, docs governance, changed-Python policy, minimum-test
- contract, changed-test assertions, diff hygiene, React type-check/lint, and
- the production web build pass. The manifest artifact/checker/test exist on
- neither side of this pre-manifest stack and are not applicable.
-- No issue or epic is completed by this propagation. Independent review,
- normal publication, protected exact-head CI, unresolved-thread checks,
- dependency integration, and release remain open.
-
-## 2026-08-11 PR #4281 wind adapter module-budget repair
-
-- The public `wind_strategy_plot_adapter.py` is reduced from 403 to 252 lines
- by extracting its request/analysis validation into the 213-line private
- `_wind_strategy_plot_validation.py` collaborator. Both now satisfy the
- mandatory below-400 production-module ceiling.
-- A frozen, slotted scenario-expectation object reduces the private scenario
- validator from five loose parameters to two cohesive parameters. Every
- production function is at or below four parameters and 50 lines.
-- Public imports, the `scalar-ensemble/v1` dataset, variable and cohort order,
- composite row identity, values, availability, attributes, validation
- messages, and the rule that adaptation never invokes flight physics are
- unchanged.
-- Local focused evidence is 14 Python adapter tests and 16 React wind tests,
- plus Ruff/format, pinned MyPy 1.13, Bandit, and the explicit line budget.
- Independent review, exact-head protected CI, ordinary publication, and
- dependency order remain required.
-
-## 2026-08-11 reviewed variation parent propagation into wind scalar PR #4281
-
-- PR `#4281` remains on `feat/4199-wind-scalar-adapter`, based on
- `feat/4144-variation-export-continuation`. Exact remote child
- `247046d55afcad3e6cd4f8029f854856c427f59c` normally merges exact reviewed
- parent `3337945699966b63cb5cd8e52d7c3b194315e911` in child-first order,
- preserving both histories without rebase, reset, retarget, force-push, or
- parent rewrite.
-- Matching Python/TypeScript `scalar-ensemble/v1` provenance, availability,
- deterministic-scenario, and wind-strategy plot-adapter behavior remain
- authoritative. The parent contributes selected-scatter export and linked
- visualization behavior, the kinetics split, Ground/Tee parity contracts,
- workspace/toolstrip repairs, and protected Ruff normalization.
-- The sole feature-code conflict referenced obsolete monolithic kinetics and
- is resolved to the validated parent `pendulum.sample(...)` facade. Both
- append-only handoff/SPEC histories are retained. This local reconciliation
- still requires independent review, fresh exact-head protected CI,
- unresolved-thread checks, dependency order, and ordinary publication before
- any merge or release claim.
-
-## 2026-08-10 Second #4280 propagation into wind scalar PR #4281
-## 2026-08-10 Repaired wind-scalar parent propagation into PR #4282
-
Status verified 2026-08-08. This isolated integration is published as draft
[PR #4217](https://github.com/D-sorganization/Tools/pull/4217). No source PR
branch was rewritten.
-## 2026-08-11 PR #4304 current-parent ancestry candidate
-
-The clean dedicated `feat/4271-ground-skid-roll` worktree first fast-forwarded
-to exact live PR #4304 child `52d9a6a978d8e6b8b19ef92f02f265c9058b00ad`,
-then normally merged exact live `feat/4270-ground-impact-bounce` parent
-`cf6e72bad98e5f36f782254942e6895b8b71e670`. The PR base remains unchanged;
-neither branch was rebased, retargeted, rewritten, force-pushed, or published.
-The automatic merge was conflict-free. Its only child-tree change before this
-documentation reconciliation is deterministic formatting in the existing
-skid/roll regression test; production physics, contracts, schemas, numerical
-ordering, and public APIs remain unchanged.
-
-Local qualification on the merge candidate is `115` focused ground
-tests passing on CPython 3.13, pinned Ruff 0.14.10 clean across the ground
-package and tests, and pinned MyPy 1.13 clean across all `25` ground production
-modules. The manifest validator and all `8` manifest tests, documentation
-governance, exact-parent and exact-child diff checks, changed-production policy,
-the official changed-file 500-LOC budget, and mandatory production limits of
-400 lines per module, 50 lines per function, and four parameters all pass. The
-local merge is a PUBLISH candidate for independent review only; protected
-exact-head CI, approval, normal child propagation, and publication remain open.
-
## 2026-08-10 PR #4304 corrected-impact propagation
Draft PR #4304 remains on `feat/4271-ground-skid-roll` with unchanged base
@@ -918,140 +505,6 @@ repair. All `115` ground tests, Ruff, formatting, a finding-free local scan of
the affected file, documentation governance, the `370`-line source-size
check, and diff gates pass before an ordinary guarded fast-forward
publication; protected CI and review remain open.
-## 2026-08-10 Final repaired #4285 propagation into PR #4288
-
-## Inherited current-parent campaign history
-
-## 2026-08-10 PR #4282 exact-head mypy repair
-
-- Hosted run `31395741841`, quality job `93478091420`, checked merge ref
- `ae75c4b006072b20a713e45b177defcc16a380fe` for exact #4282 head
- `aa6eeffb0395f7ed7954f2315b1c625cada552d8`.
-- Checkout, installation, Ruff, and format passed. Pinned mypy 1.13 failed only
- `scripts/rate_campaign_manifest.py:335:5 [no-any-return]` because the exact
- skipped-import profile treats Pydantic's validator result as `Any`.
-- The validated local now has an explicit `CampaignManifest` annotation. This
- preserves the strict JSON contract and avoids both a suppression and the
- redundant cast reported by the non-skipped profile.
-- The failed run belongs to the obsolete head. Publish normally, preserve the
- PR base/draft state, and propagate the resulting exact head into #4285.
-
-## 2026-08-10 Exact #4281 propagation into wind workflow PR #4282
-
-- PR `#4282` remains on `feat/4199-wind-workflow`, based on
- `feat/4199-wind-scalar-adapter`.
-- Original child `5f77af4add23547a21cc3fabce98ae9ad4260427` normally merges exact
- parent `4a793c4c3f19aad43a3c215800b266be487ace49`; preserve that parent order
- and do not rebase, retarget, force-push, rewrite a parent, change draft state,
- or merge the PR.
-- The responsive PyQt6/React wind workflow, consolidated capability stack, and
- campaign release authority remain additive with the parent's strict
- scalar-ensemble wind adapter, variation visualization, result-local
- selection, workspace/toolstrip, and Python 3.10 compatibility repairs.
-- The canonical navigation-state tuple now includes the child-owned capability
- tab while retaining the parent's legacy-order visibility migration; no
- duplicate navigation constant remains.
-- Static review replaces optimized-away UI/capability assertions with explicit
- runtime invariant failures and records the fixed-argument executable builder
- subprocess boundary using Bandit's native suppression syntax. The separate
- exact-CI Pydantic return repair is recorded above.
-- SPEC 1.14.14 is the unique combined child entry. Verification passes 73
- focused Python tests, the complete 1,657-test Rate/shared-swing/golf-club
- matrix with two explicit optional build123d skips, 643 React tests across 105
- files plus type-check/lint/build, 12 Rust tests, 31 real-CPython-3.10
- compatibility tests, and 43 post-review invariant/GUI/manifest tests.
- Ruff/format, pinned MyPy 1.13 across 37 changed production files, Bandit,
- exact-parent size, manifest, docs, minimum-test, assertions, CI-policy
- secrets, compilation, and diff gates pass. Independent re-review found no
- actionable findings after 94 Python workflow/navigation tests, 20
- manifest/GUI tests, 61 React workflow tests, and independent static checks.
- Protected current-head CI, unresolved threads, and repository review remain
- release gates after publication.
-## 2026-08-09 PR #4282 corrected-parent propagation
-
-Draft #4282 remains on `feat/4199-wind-workflow` with unchanged base
-`feat/4199-wind-scalar-adapter`. Exact corrected #4281 parent
-`958770049f0124dac0426a6dd62fd4edbf437e7a` is incorporated by the normal
-local merge containing this handoff; no branch was rebased, retargeted,
-force-pushed, or published. The result preserves the responsive PyQt6/React
-wind-strategy workflow, the consolidated capability stack, release-manifest
-authority, and launcher/type-gate repairs while inheriting the complete
-Python 3.10 compatibility, variation-export, and scalar-ensemble corrections.
-
-## 2026-08-09 Capability workflow hardening continuation
-
-Local branch `feat/4201-capability-contract-hardening` starts at exact carrier
-`18fe89201d657116bbca99922297c14968356c44`. It makes the Python and TypeScript
-`capability-optimization-workflow/v1` readers fail closed on JSON primitive
-type mismatches and pins the identical accept/reject matrix in a shared golden
-fixture. The Python reader validates the complete nested wire document before
-calling model constructors, so numeric strings, booleans-as-numbers, numeric
-text identifiers/provenance, and fractional integer fields cannot be silently
-normalized. Integral JSON numbers remain portable between runtimes.
-
-The React Shot Optimizer also replaces browser-managed number inputs with
-decimal text drafts. This makes leading-minus and decimal entry reliable while
-preserving numeric commit and existing workflow validation. RED evidence was
-Python `8 failed, 16 passed` and React `2 failed, 26 passed`; final focused
-evidence is Python `43 passed`, React `9 files / 69 tests passed`, with Ruff,
-format, mypy, TypeScript, ESLint, structural, and diff checks clean. This
-continuation also builds 187 Vite modules without a size warning; it is local
-only and has not changed GitHub state.
-
-## 2026-08-10 Final repaired #4282 propagation into PR #4285
-
-- Draft PR `#4288` keeps branch `feat/4269-flight-ground-transfer`, base
- `feat/4268-ground-contract`, and original child
- `108a841b1378c992defd3c7b7ee263d41a6c8b24` first.
-- Exact quality-green strict-contract head
- `a93edb4bfd6a8dc9334122cd2ae660983d5bf424` is the second parent.
-- Only the four canonical handoff/spec files conflicted; transfer production
- and tests did not. No history or topology rewrite was used.
-- Fresh exact-head protected CI and review remain mandatory; queued checks are
- not release evidence.
-
-## 2026-08-10 PR #4288 exact repaired-ground propagation
-
-Draft PR #4288 remains on `feat/4269-flight-ground-transfer` with unchanged
-base `feat/4268-ground-contract`. Original child
-`247215422a6d4b677552955b4923bc609a553259` normally incorporates exact repaired
-#4285 parent `e5bcbd1096d3be1f621a805c9d9f3fd321e375a5` second in the
-merge containing this handoff. The child retains its qualified signed terminal state,
-physical sphere/terrain contact brackets, strict provenance, and cross-runtime
-Python/TypeScript/Rust/PyO3/WASM contracts while inheriting deterministic
-workspace timestamps, canonical `swing_sim` import identity, the hosted-mypy
-manifest repair, and the complete variation, wind, capability, and campaign
-ancestry. No branch was rebased, retargeted, rewritten, or force-pushed.
-
-This propagation does not add bounce, skid, roll, terrain response, total
-distance, or UI execution. Protected CI, independent review, and normal
-dependency-ordered collapse remain separate release gates.
-
-Exact composed-tree verification is 1,080 Python tests passed with six explicit
-optional installed-`tools_core` wheel skips, 107 React files / 662 tests,
-26 direct Rust transfer/wire tests, TypeScript, zero-warning ESLint, and the
-189-module production build. Ruff check/format passes all 28 changed Python
-files; pinned mypy 1.13 passes all 21 changed production files. Campaign
-manifest validation, documentation governance, and diff checks are clean. The
-missing local wheel is not accelerated installed-package evidence and remains
-an explicit release boundary; the direct Rust suites executed rather than
-being relabeled as wheel parity.
-
-## 2026-08-10 Exact repaired #4282 propagation into PR #4285
-
-Draft PR #4285 remains on `feat/4268-ground-contract` with unchanged base
-`feat/4197-capability-observer`. Original child
-`788aa547651a3685a363ea401824a5d81477bafb` normally incorporates exact
-repaired #4282 carrier `686016196a2f895058b8a566dff103a0fd32cd10`
-second. That parent contains merged capability PR #4283 commit
-`c1827bbdc50a6e11cc475db2636b4e47a4c15416`, exact observer head
-`9bbb98e16e435a0d4c74153b909f2ebfefbbce7a`, and the hosted pinned-mypy
-manifest repair. The strict ground-contract child retains its
-schemas, canonical fixture, migrations, legacy-result adapter, declared
-dependency, and pinned typing repairs while inheriting the deterministic Python
-3.10-3.12 UTC parser and the corrected variation, scalar, wind, capability, and
-campaign-release ancestry. No branch was rebased, retargeted, rewritten, or
-force-pushed.
## 2026-08-09 PR #4304 corrected implementation evidence
@@ -1064,29 +517,6 @@ all pass locally. This registry/handoff commit is documentation-only and makes
no material runtime, physics, numerical, schema, or API change. Fresh
protected CI and review remain required after an ordinary guarded push.
-## 2026-08-10 Exact repaired #4282 propagation into PR #4285 (continued)
-
-The inherited ground descendant passes 1,703 Python tests with two optional `build123d`
-skips, 643 React tests across 105 files plus type-check/lint/build, 12 Rust tests,
-and 77 real-CPython-3.10 ground and compatibility tests. Ruff/format pass 78
-changed Python files; pinned mypy and Bandit pass 52 changed production files.
-Manifest, docs, minimum-test, assertions, 500-LOC, changed-file secrets, Python
-3.10 compilation, and diff checks are clean. Hosted CI and review still apply
-only to the new exact head. That repaired ground head is now incorporated into
-#4288; normal propagation of the reviewed #4288 head into #4298 is the next
-ancestry gate.
-
-The repaired parent owns the explicit Pydantic manifest annotation. The
-composed tree additionally normalizes contract-checked scalar plot values,
-enforces disabled-command invariants under optimized Python, and documents the
-optional alias finder's reviewed catch-and-continue security boundary.
-
-This is ancestry reconciliation, not new landing physics. Qualified bounce,
-skid, roll, terrain profiles, total distance, UI execution, Rust/WASM parity,
-protected CI, review, and release remain open. The exact repaired #4285 head is
-now incorporated into #4288; the transfer behavior is evaluated on that
-corrected descendant before normal propagation into #4298.
-
## 2026-08-09 PR #4304 isolated-MyPy correction
Hosted quality-gate run `31354071845` (job `93350276996`) failed exact
@@ -1236,32 +666,6 @@ terrain deformation, UI, TypeScript physics, Rust/PyO3/WASM, and UpstreamDrift
adapters remain excluded. Protected CI, required review, ordinary parent
integration, and downstream delivery are still required.
-## 2026-08-09 PR #4285 corrected-carrier reconciliation
-
-Draft #4285 remains on `feat/4268-ground-contract` with unchanged base
-`feat/4197-capability-observer`. Exact corrected wind carrier
-`bb101cedd555d07d493aae998b46050c68660cdd` is incorporated through the
-normal local merge containing this handoff; no branch was rebased, retargeted,
-force-pushed, or published. The ground parent retains its strict schemas,
-canonical fixture, migrations, legacy-result adapter, explicit dependency, and
-pinned-mypy repairs while acquiring the corrected wind/scalar/variation,
-Python 3.10 compatibility, capability, and campaign-release ancestry.
-
-This is an ancestry reconciliation, not new landing physics. Qualified bounce,
-skid, roll, terrain profiles, total distance, UI, Rust/WASM parity, protected
-CI, review, and release remain open. PR #4288 must normally merge the resulting
-exact #4285 head and rerun its transfer and combined compatibility gates. That
-next propagation is where the descendant acquires the observer-to-wind
-reconciliation; neither PR base should change.
-Draft #4282 remains on `feat/4199-wind-workflow` with unchanged base
-`feat/4199-wind-scalar-adapter`. Exact corrected #4281 parent
-`958770049f0124dac0426a6dd62fd4edbf437e7a` is incorporated by the normal
-local merge containing this handoff; no branch was rebased, retargeted,
-force-pushed, or published. The result preserves the responsive PyQt6/React
-wind-strategy workflow, the consolidated capability stack, release-manifest
-authority, and launcher/type-gate repairs while inheriting the complete
-Python 3.10 compatibility, variation-export, and scalar-ensemble corrections.
-
## 2026-08-09 PR #4288 corrected-ground-parent propagation
Draft #4288 remains on `feat/4269-flight-ground-transfer` with unchanged base
@@ -1329,443 +733,6 @@ against a `1e-12` absolute tolerance. This branch does not change the wind
workflow. The hosted Rust `-lpython3.11` linker failure remains runner/toolchain
infrastructure.
-## Additional inherited parent campaign history
-
-This is an ancestry reconciliation, not new landing physics. Qualified bounce,
-skid, roll, terrain profiles, total distance, UI, Rust/WASM parity, protected
-CI, review, and release remain open. PR #4288 must normally merge the resulting
-exact #4285 head and rerun its transfer and combined compatibility gates. That
-next propagation is where the descendant acquires the observer-to-wind
-reconciliation; neither PR base should change.
-Draft #4282 remains on `feat/4199-wind-workflow` with unchanged base
-`feat/4199-wind-scalar-adapter`. Exact corrected #4281 parent
-`958770049f0124dac0426a6dd62fd4edbf437e7a` is incorporated by the normal
-local merge containing this handoff; no branch was rebased, retargeted,
-force-pushed, or published. The result preserves the responsive PyQt6/React
-wind-strategy workflow, the consolidated capability stack, release-manifest
-authority, and launcher/type-gate repairs while inheriting the complete
-Python 3.10 compatibility, variation-export, and scalar-ensemble corrections.
-## 2026-08-11 current workspace propagation into variation PR #4280
-
-- PR `#4280` remains on `feat/4144-variation-export-continuation`, based on
- `feat/4218-toolstrip-workspace`. Exact published child
- `3337945699966b63cb5cd8e52d7c3b194315e911` is the first parent and exact
- newly published workspace head `efbca84095b617b4018732f7802c2da3f0525387`
- is the second parent of this normal local merge.
-- Production and test paths merge automatically. Variation selected-scatter
- CSV parity, typed unavailable outcomes, bounded accessible tables, linked
- selection, and all-trial arc analysis remain authoritative while inheriting
- the parent's current workspace/toolstrip, launch-monitor/D-plane ancestry,
- split kinetics, and Qt typing repairs. Only the three canonical handoffs and
- SPEC conflict textually; both append-only histories are retained.
-- Focused pre-commit regression is green: 56 Python variation tests and all 10
- tests in the three focused React variation suites pass. Exact post-commit
- PR-delta gates are also green: pinned Ruff 0.14.10 checks/formats five changed
- Python files, pinned MyPy 1.13.0 accepts four production files, and pinned
- Bandit 1.7.7 finds no issues in those four files. Docs governance, 500-LOC
- budget, changed-Python policy, minimum-test contract, changed-test assertions,
- diff hygiene, React type-check/lint, and the production web build pass. The
- manifest artifact/checker/test exist on neither side of this pre-manifest
- stack, so that later release gate is structurally not applicable.
-- No issue or epic is completed by this propagation. Independent review,
- normal publication, protected exact-head CI, unresolved-thread checks,
- dependency integration, and release remain open.
-
-## 2026-08-11 reviewed workspace parent propagation into variation PR #4280
-
-- PR `#4280` remains on `feat/4144-variation-export-continuation`, based on
- `feat/4218-toolstrip-workspace`. Exact remote child
- `668ba96746f79f7a12e8092161bd610054197f58` normally merges exact reviewed
- parent `ccd0e026c580c93038fdf5c59d5d452a85ba27a0` in child-first order,
- preserving every commit and both histories without rebase, reset, retarget,
- force-push, or parent rewrite.
-- Variation selected-scatter CSV parity, typed unavailable outcomes, bounded
- accessible tables, linked selection, and all-trial arc analysis remain
- authoritative. The parent contributes its validated kinetics split,
- Ground/Tee parity contracts, protected Ruff normalization, complete
- workspace/toolstrip behavior, and remote-history reconciliation.
-- The sole feature-code conflict was obsolete monolithic kinetics source and
- is resolved to the current `pendulum.sample(...)` façade. Both append-only
- handoff histories are retained. Seven duplicate child automation edits fail
- protected Ruff 0.14.10 formatting and are normalized to exact reviewed
- parent blobs without removing their commit from history. This local merge
- still requires independent review, fresh exact-head protected CI,
- unresolved-thread checks, dependency order, and ordinary publication before
- any release or merge claim.
-
-## 2026-08-10 Second #4279 propagation into variation PR #4280
-
-- PR `#4280` stays on `feat/4144-variation-export-continuation`, based on
- `feat/4218-toolstrip-workspace`.
-- Exact repaired parent `61b7f48b5aeb7d57246b4963da3df086e79cbe15`
- is incorporated through a normal merge commit. No feature code conflicts and
- no branch/PR topology or parent history is rewritten.
-- Preserve the variation/export implementation and both append-only handoff
- histories. Fresh protected CI, review, and dependency order remain open.
-- Post-reconciliation evidence is 25 focused D-plane/impact tests plus docs
- governance, changed-file-size, and whitespace gates.
-
-## 2026-08-10 Exact #4279 propagation into variation PR #4280
-
-- PR `#4280` remains the immediate child on
- `feat/4144-variation-export-continuation`, based on
- `feat/4218-toolstrip-workspace`.
-- Original child `f90836e342efc8be624739802375af2876d11e5f` normally merges
- exact parent `6717e9e09d507dbc24bedb36177f1cdf0b4fd90b`; preserve that
- parent order and do not rebase, retarget, force-push, rewrite a parent, or
- change draft state.
-- The variation selected-scatter export, typed unavailable rows, accessible
- raw tables, linked trial selection, and focused PyQt/React visualization
- modules merge cleanly with the parent's full workspace/toolstrip, playback,
- plots, navigation, compatibility, and module-budget repairs.
-- Staged review found a release-blocking stale linked selection after rerunning
- a smaller study. PyQt now clears selection before each result replacement
- and validates public selection indices against the current trial count;
- React clears on result identity change and bounds the value shared with all
- linked views. Larger-to-smaller rerun regressions cover both clients.
-- SPEC 1.14.12 is the unique combined child release entry. Verification is
- green across 37 focused variation tests, 1,528 complete
- Rate/shared-swing/golf-club tests with two explicit optional build123d skips,
- 546 React tests across 90 files plus type-check/lint/build, exact-parent
- Ruff/Ruff-format/Black/pinned MyPy/Bandit, file-size, docs, minimum-test,
- assertion, detect-secrets, diff, real CPython 3.10.20 compilation, and 30
- compatibility regressions. There is no Rust delta from the exact parent.
- Independent staged re-review found no actionable findings after checking
- both the first replacement-render React boundary and validated PyQt values.
- Current-head protected CI, review threads, and repository review remain
- release gates after publication.
-## 2026-08-11 current #4203 propagation into workspace PR #4279
-
-- PR `#4279` remains on `feat/4218-toolstrip-workspace`, based on
- `feat/4181-launch-monitor-registry`. Exact published child
- `ccd0e026c580c93038fdf5c59d5d452a85ba27a0` is the first parent and exact
- newly published #4203 head `7abce9ad767fe8311da66a1e5998b892ea3ca9de`
- is the second parent of this normal local merge.
-- Production and test paths merge automatically. Workspace/toolstrip,
- module-visibility, navigation, granular playback, and independent plots are
- preserved while the descendant inherits the parent's current launch-monitor,
- D-plane, split-kinetics, and Qt typing repairs. Only the three canonical
- handoffs and SPEC conflict textually; both append-only histories are retained.
-- Focused pre-commit regression is green: 142 exact PR-delta Python tests pass,
- and all 32 tests in the eight changed React suites pass. Exact post-commit
- PR-delta gates are also green: pinned Ruff 0.14.10 checks/formats 27 changed
- Python files, pinned MyPy 1.13.0 accepts 18 production files, and pinned
- Bandit 1.7.7 finds no medium/high issues in those 18 files. Docs governance,
- 500-LOC budget, changed-Python policy, minimum-test contract, changed-test
- assertions, diff hygiene, React type-check/lint, and the production web build
- pass. The manifest artifact/checker/test exist on neither side of this
- pre-manifest stack, so that later release gate is structurally not applicable.
-- No issue or epic is completed by this propagation. Independent review,
- normal publication, protected exact-head CI, unresolved-thread checks,
- dependency integration, and release remain open.
-
-## 2026-08-11 remote automation reconciliation for workspace PR #4279
-
-- PR `#4279` remains on `feat/4218-toolstrip-workspace`, based on
- `feat/4181-launch-monitor-registry`. Exact local head
- `0b22c401a26c31441a599d8d9b39de123706e7ea` ordinarily merges exact remote
- head `61fe2d556a5413e525d958612ccfd57e65b8d5a2`; both histories and every
- commit remain reachable without reset, rebase, force-push, retarget, or
- parent rewrite.
-- The remote automation commit spans 23 paths but is formatting-only. Fifteen
- paths were already byte-identical through the current parent, including its
- six existing `.codex-worktrees` gitlinks. Its seven unique formatting edits
- do not match protected Ruff 0.14.10 output and are normalized back to the
- pinned form. The sole content conflict was between obsolete pre-split
- kinetics source and the current façade; resolution retains the current
- `pendulum.sample(...)` implementation and parent module split.
-- No workspace/toolstrip feature code is lost. Module visibility, navigation,
- granular playback, independent plots, physics, frames, units, schemas, and
- public contracts remain unchanged. Fresh exact-head protected CI,
- independent review, unresolved-thread checks, dependency order, and normal
- publication are still required; this local merge is not a release claim.
-
-## 2026-08-11 hosted MyPy repair propagation into workspace PR #4279
-
-- PR `#4279` remains on `feat/4218-toolstrip-workspace`, based on
- `feat/4181-launch-monitor-registry`. Exact child
- `7806a16f58e1c6999d32f0127a187fbb21f839a1` normally merges exact published
- parent `3796b49e40b677fbac4e05739f8be49f905df2cb` without rebase, retarget,
- force-push, or history rewrite.
-- There are no feature-code conflicts. The only inherited production changes
- are four static NumPy-array casts that close hosted MyPy return boundaries;
- workspace/toolstrip behavior and numerical, frame, unit, schema, rendering,
- and public-API semantics remain unchanged.
-- Preserve both append-only histories below. This local merge requires fresh
- merged-tree protected CI, required review, unresolved-thread checks, and
- dependency order before publication or merge.
-
-## 2026-08-11 latest #4203 propagation into workspace PR #4279
-
-- PR `#4279` remains on `feat/4218-toolstrip-workspace`, based on
- `feat/4181-launch-monitor-registry`; exact parent
- `0216a547aa79727091a2939b96e779e8ddbd7304` is incorporated by a normal
- two-parent merge without rebase, retarget, force-push, or history rewrite.
-- There are no feature-code conflicts. The child retains its workspace,
- toolstrip, module-visibility, navigation, granular playback, and independent
- plot behavior while inheriting the parent's pinned formatting and
- identity-preserving 222/205/131-line kinetics split.
-- Preserve both append-only histories below. Fresh merged-tree protected CI,
- required review, unresolved-thread checks, and dependency order remain
- release gates; this local merge is not a completion or publication claim.
-
-## 2026-08-10 Second #4203 propagation into workspace PR #4279
-
-- PR `#4279` remains the immediate child on
- `feat/4218-toolstrip-workspace`, based on
- `feat/4181-launch-monitor-registry`.
-- Exact repaired parent head
- `12dd76a8dbcc106c4683f2f2e53076f8dc6f1b76` is incorporated through a
- normal merge commit; no feature code conflicts and no branch or PR topology
- is rewritten.
-- Preserve both append-only handoff histories. Fresh child protected CI,
- review, and earlier dependency gates remain required.
-- Post-reconciliation evidence is 25 focused D-plane/impact tests plus docs
- governance, changed-file-size, and whitespace gates.
-
-## 2026-08-10 Exact #4203 propagation into workspace PR #4279
-
-- PR `#4279` remains the immediate child on branch
- `feat/4218-toolstrip-workspace`, based on
- `feat/4181-launch-monitor-registry`.
-- Original child `05383d333b6fd87eaf5e37305476f50b505c2c2e` normally merges
- exact parent `31cbc007d4c85b5479b7cd0fb0969124eab2af67`; preserve that
- two-parent order and do not rebase, retarget, force-push, or change draft
- state.
-- The child workspace/toolstrip, module-visibility, granular playback, path
- trail, and independent plot behavior remain authoritative. The parent
- `ImpactLayerControls`, navigation-state constants, plotting catalog, and
- triple-pendulum extractions are integrated without duplicate state.
-- Verification is green across 1,339 Python tests with six explicit skips, 545
- React tests plus type-check/lint/build, the 40-test post-format PyQt rerun,
- exact-parent Ruff/Ruff-format/Black/pinned MyPy/Bandit, the 500-line budget,
- docs/minimum-test/assertion/detect-secrets/diff gates, real CPython 3.10.20
- compile/import checks, and 30 compatibility regressions. There is no Rust
- delta from the exact parent. Independent staged review found no actionable
- findings after 76 additional focused PyQt/navigation/workspace tests.
- Current-head protected CI, unresolved-thread checks, and required repository
- review remain release gates after guarded publication.
-
-## 2026-08-11 #4203 append-only SPEC preservation repair
-
-- Independent review of local candidate `e20b4f630...` found four exact
- current-parent history rows missing from SPEC: 2026-08-10 versions 1.13.11,
- 1.13.9, 1.13.7, and 1.13.6. The current documentation-only follow-up restores
- those rows verbatim and advances the declared/changelog version together.
-- Runtime files, tests, ordered merge parents, PR base, and validation evidence
- are byte-unchanged. Re-review, normal publication, exact-head protected CI,
- and downstream propagation remain required.
-
-## 2026-08-11 #4203 current-parent reconciliation
-
-- The current D-plane base is exact head
- `f3363aa88868f6a5c7e9ccfc682a9eca014e86c1`; #4203's exact published child
- is `217e36dc93d30f79826847f958fbcd10805e58ed`. They are being composed in
- that order by a normal merge while retaining base `feat/4189-dplane`.
-- The parent's nine changed files merge without semantic conflict except for
- formatting around the inherited kinetics origin offset. The split child
- facade remains authoritative because the obsolete parent expression reaches
- through `source.inner`; the equivalent explanatory comment is preserved.
-- The exact CI-pinned MyPy 1.13 delta found four additional Qt-stub `Any`
- boundaries after the merge. Explicit `bool`/`str` narrowing now closes the
- responsive-event, legend, ball-setup event-filter, and status-text contracts
- without changing their runtime values or interaction behavior.
-- No issue or epic is complete from this reconciliation. Independent review,
- ordinary publication, protected CI, downstream propagation, and release
- gates remain open.
-
-## 2026-08-11 #4203 exact-head format completion
-
-- Exact published head `7d69a545ae555679f0318940e67c1786626d6794`
- failed only the Ruff format step. The exact pinned 0.14.10 reproduction found
- eleven noncompliant changed files: four inherited files plus seven altered by
- the automated pre-commit repair.
-- The pending correction is mechanical Ruff formatting of those eleven files.
- It changes no runtime behavior or public contract and still requires AST
- equivalence, focused tests, independent review, ordinary fast-forward
- publication, and fresh protected exact-head CI.
-
-## 2026-08-11 #4203 hosted MyPy NumPy boundary repair
-
-- Exact PR head `0216a547aa79727091a2939b96e779e8ddbd7304` reached runtime merge
- ref `aede309` but failed CI Standard run `31477542889`, job `93734652129`,
- with four `no-any-return` findings introduced when kinetics was split for the
- size budget.
-- Explicit `numpy.ndarray` casts now close only the static return boundaries
- around force norms, the RK4 derivative concatenation, and the app-frame
- projection. There is no numerical operation, copy, schema, frame, unit,
- rendering, or public API change.
-- The acceptance profile is the entire 102-file PR-base changed-source MyPy
- set, followed by focused kinetics/presentation/PyQt tests, the full Rate
- suite, and the repository's Ruff/format, size, Bandit, documentation, and
- diff gates. A three-file MyPy pass alone is insufficient release evidence.
-- That local profile is now green: MyPy 102 files; Ruff/format 141 files;
- Bandit 101 production files with no medium/high finding; 28 focused and 701
- full Rate tests; plus module/file size, documentation, minimum-test, and diff
- gates.
-- The fix remains local pending independent review and ordinary protected CI.
- Do not resume #4279 propagation from an unreviewed or unpublished commit.
-
-## 2026-08-11 #4203 kinetics size-budget repair
-
-- The exact `572bf525d` PR tree passes its base-relative candidate scan, but
- `python scripts/check_file_size_budget.py --max-loc 500 --changed-only
- --base-ref HEAD~1 --baseline-file scripts/monolith_baseline.txt` reproduces
- the proactive release failure: Ruff-formatted `simulation/kinetics.py` is
- selected at 646 LOC and is not grandfathered.
-- A behavior-preserving extraction leaves a 222-LOC stable public façade and
- delegates immutable result validation (131 LOC) and pure pendulum dynamics
- (205 LOC) to focused private modules. Public export identity and the existing
- `_reaction_forces` compatibility seam are test-pinned.
-- Existing numerical parity, inverse/forward dynamics, energy, reaction-force,
- presentation, and PyQt behavior remain the acceptance basis. This local-only
- implementation does not change PR base, stack order, protected review/CI
- requirements, or any downstream issue completion state.
-- Local regression evidence is 28 focused kinetics/presentation/PyQt tests
- and all 701 Rate-of-Closure Python tests passing.
-
-## 2026-08-11 #4203 pinned-Ruff formatting repair
-
-- No material handoff change: the eight Python files reported by CI Standard
- run `31468208320`, job `93705508050`, receive only the repository-pinned
- Ruff 0.14.10 formatting output.
-- No physics, behavior, frame, schema, UI, release-stack, or dependency
- contract changes. Current-head protected CI and review remain release
- requirements; queued checks remain unresolved rather than passing.
-
-## 2026-08-10 #4143 child receives repaired launch-registry parent
-
-- Ready PR `#4325` stays on `feat/4143-tee-parity-fixture`, based on
- `feat/4181-launch-monitor-registry`.
-- Exact parent `12dd76a8dbcc106c4683f2f2e53076f8dc6f1b76` is incorporated by a
- normal merge commit. There is no production/test-code conflict and no
- rebase, retarget, force-push, or parent rewrite.
-- Preserve the shared parity fixture and deterministic web/PyQt evidence.
- Fresh exact-head CI, review, dependency order, and release to `main` remain
- required before #4143 can close.
-
-## 2026-08-10 #4143 Python/React golden ball-setup parity
-
-- The bounded `feat/4143-tee-parity-fixture` branch starts at exact PR #4203
- head `31cbc007d4c85b5479b7cd0fb0969124eab2af67`, preserving its draft state,
- base, and stack order.
-- A single `ball_setup_golden_v1.json` fixture declares schema/version, metre
- units, the ground-plane-to-ball-bottom reference, ball radius, Driver/Tee and
- iron/Ground defaults, explicit club-default overrides, Ground zero effective
- height, center/serialization geometry, invalid finite-domain cases, and a
- legacy simulation-run migration.
-- Python and React independently consume every case through their public
- configuration/persistence boundaries. Verification is 18 passing Python
- tests, 24 passing React tests, and green TypeScript, ESLint, Vite production
- build, Ruff check, and Ruff format.
-- Recorded visual evidence is stored under
- `C:\Users\diete\AppData\Local\Temp\rate-4143-visual-evidence-8050eeba`.
- Playwright captured the 1600 x 1200 default Driver/Tee and rerun
- explicit-Ground React states after semantic control/diagram and zero-error
- checks. A hidden 1400 x 900 PyQt harness captured the same states after
- canonical center, editor, and tee-artist assertions. The browser manifest
- SHA-256 is `43df78e04b47e1b3209ff7a574718f90847ccda6dde5afd863d43191a950ccf7`;
- the PyQt manifest SHA-256 is
- `07822495dbcfa7568615ccb2728481210c28963614434c80f6997210c325a6f9`.
- PNGs remain external evidence rather than oversized repository binaries.
-- #4143 remains open for protected CI/review and release to `main`. The strict
- campaign release manifest does not exist in this exact #4203 history; it was
- added later on a divergent branch and is not backported by this bounded
- slice.
-
-## 2026-08-10 Second propagation into launch-monitor registry
-
-- Draft child PR `#4203` retains base `feat/4189-dplane` and receives exact
- repaired parent head `7d8d2f06dc797021d01939691e58f8425b652b33`
- through a normal merge commit. No branch history, PR base, or draft state is
- rewritten.
-- The inherited repair closes the parent head's two pinned MyPy
- `no-any-return` findings with explicit ndarray boundaries and makes no
- numerical, frame, schema, or UI change.
-- Parent quality-gate success is not child release evidence. Current-head child
- CI, review, all earlier ancestors, and #4189 acceptance remain required.
-- Reconciled child-tree evidence is 25 focused D-plane/impact tests, docs
- governance, changed-file size, and whitespace checks. The local Windows
- MyPy 1.15/installed-NumPy stub combination is incompatible with the branch's
- Python 3.11 target, while WSL currently fails to start with `E_FAIL`; the
- successful pinned typing evidence remains the exact parent hosted gate.
-
-## 2026-08-10 Propagation into launch-monitor registry
-
-- Immediate child PR `#4203` keeps base `feat/4189-dplane`.
-- Its original head `08a2fdd8ce6bbc8fbb8f121927a677d4addb6b11`
- normally merges exact parent `#4202` head
- `b443fdbed7064c5db0320106013c8413e3e24356`; no branch rewrite, retarget,
- or force push is permitted.
-- The semantic reconciliation keeps #4203's responsive
- `SimulationViewControlsMixin`, while the parent's `ImpactLayerControls`
- helper becomes the single owner of persisted D-plane checkbox state. The
- automation compatibility mapping aliases that helper state exactly.
-- The launch-monitor registry, Python 3.10 compatibility layer, frame-explicit
- D-plane contracts, responsive layout, and exports remain additive. Both
- affected PyQt modules satisfy the protected 500-line limit.
-- The untouched original child had three additional ungrandfathered size
- blockers: swing sources at 540 LOC, the plotting catalog at 533 LOC, and the
- main window at 528 LOC. Narrow extractions move triple-pendulum dynamics,
- plotting metadata, and versioned primary-tab state into focused modules,
- while identity-pinned re-exports preserve every established import seam. The
- resulting module pairs are 282/282, 459/98, and 494/85 lines.
-- Focused evidence is 36 passing PyQt simulation/layout tests, 38
- plotting/navigation tests, and 21 simulation source/export tests. Combined
- evidence is 1,249 passing Python tests with six explicit optional skips, 521
- React tests and all web gates, 12 `swing-core` tests, real CPython 3.10
- checks, scoped static analysis, docs/minimum-test/assertion governance,
- changed-file size, detect-secrets, and diff checks. The protected size gate
- passes all 107 changed candidates; a separate full-tree audit retains two
- untouched non-candidate monoliths (`kinetics.py` and
- `torque_profile_panel.py`). Independent staged review found no actionable
- findings after 95 additional focused tests. Current-head protected CI and
- required repository review remain pending release evidence.
-
-Status verified 2026-08-07. This isolated integration is published as draft
-[PR #4217](https://github.com/D-sorganization/Tools/pull/4217). No source PR
-branch was rewritten.
-## 2026-08-10 PR #4281 workspace timestamp propagation
-
-Exact parent `f90836e342efc8be624739802375af2876d11e5f` is incorporated into
-`feat/4199-wind-scalar-adapter` through the normal merge containing this
-handoff. PR #4281 keeps base `feat/4144-variation-export-continuation`; no
-branch was rebased, retargeted, rewritten, or force-pushed. The child retains
-its scalar ensemble and wind adapter while inheriting the deterministic UTC
-parser and complete variation parent.
-
-The monotonic SPEC now assigns 1.14.10 to compatibility, 1.14.11 to variation,
-and 1.14.12 to the wind child. The reconciled tree passes `794` Rate tests,
-`27` direct compatibility tests on real CPython 3.10.20, and `2 files / 10`
-focused React tests, plus TypeScript, focused zero-warning ESLint, Ruff,
-format, pinned mypy 1.13, documentation, size, and diff gates. Protected CI,
-review, and later propagation remain open.
-
-## 2026-08-09 PR #4281 scalar-ensemble parent propagation
-
-Draft #4281 remains based on `feat/4144-variation-export-continuation` and now
-includes exact corrected #4280 parent
-`38ed58cab96842a3007e76a855db83ee2452b8fd` through the normal merge containing
-this handoff. No branch was rebased, retargeted, force-pushed, or published.
-The child retains its matching Python/TypeScript `scalar-ensemble/v1` contract
-and wind-strategy adapter while inheriting the full variation-export and
-Python 3.10 compatibility history. SPEC 1.14.12 records this child source delta
-independently and monotonically above parent 1.14.11.
-
-SPEC 1.14.13 records the current #4282 propagation monotonically above the
-corrected parent's 1.14.12, 1.14.11, and 1.14.10 entries. Protected CI, review,
-publication, installed-package evidence, downstream UpstreamDrift parity, and
-the remaining scientific/accessibility/performance release gates remain
-separate. This local merge is not a protected release.
-
-Focused evidence is 89 ground-contract, compatibility, scalar-adapter, and
-responsive-wind tests on Python 3.11 plus the same 89 on real CPython 3.10.20.
-Ruff check/format passes 34 focused Python files, pinned mypy 1.13 passes 23
-production modules, and ground modules/functions remain within 400/50-line
-budgets without placeholders. The inherited campaign manifest validates and
-all nine manifest/parity contracts pass. Documentation governance, ancestry,
-SPEC-order, and final diff assertions are required in the same local merge.
-
## 2026-08-09 Ground-contract stack recovery
Protected quality-gate run `31341468033` on PR #4285 exact head
@@ -2366,10 +1333,8 @@ an explicit mocked-integrator regression test for that boundary.
Current exact local evidence is 906 Python/PyQt/shared-swing tests passed with
one expected optional-Rust skip and 15 existing warnings, plus 91 React test
files / 555 tests passed. Ruff, formatting, Black, focused mypy, TypeScript,
-zero-warning ESLint, the 166-module production build, and `git diff --check`
-passed. The function budget passed, but the 403-line wind adapter did not meet
-the mandatory below-400 module ceiling at that historical head; the
-2026-08-11 repair above corrects that blocker. The adapter is plot-ready model
+zero-warning ESLint, the 166-module production build, `git diff --check`, and
+the production module/function budgets pass. The adapter is plot-ready model
infrastructure, not an end-user workflow; #4199 remains open for worker,
progress/cancellation, client controls, strategy/scatter displays,
persistence, and exports.
@@ -2764,6 +1729,7 @@ existing local SciPy/NumPy compatibility warning also remains environmental.
All new source files are below 400 lines. The oversized append-only SPEC and
handoff registries plus the preserved Waterloo and `from_imperial` public
signatures predate #4269 and are explicitly retained for compatibility.
+
## 2026-08-09 PR #4302 deterministic-digest scanner repair
The protected run at exact PR #4302 head
@@ -2776,477 +1742,3 @@ The digest, fixture, physics, scanner scope, and baseline remain unchanged.
Commit and push this bounded repair normally before propagating it into #4304,
#4305, or later ground children. The contemporaneous file-size cancellation
occurred in checkout and remains infrastructure evidence, not a code failure.
-## 2026-08-11 parent sections preserved during #4282 reconciliation
-
-## 2026-08-10 Exact #4280 propagation into wind scalar PR #4281
-
-- PR `#4281` remains on `feat/4199-wind-scalar-adapter`, based on
- `feat/4144-variation-export-continuation`.
-- Original child `cf52529b1e68479321bb93b1be3d59c77f782008` normally merges
- exact parent `8bcc49fc4e16e5e43be0b7f0f03c3017d5b79d0c`; preserve that
- parent order and do not rebase, retarget, force-push, rewrite a parent, or
- change draft state.
-- The Python/TypeScript `scalar-ensemble/v1` contract and wind-strategy plot
- adapter retain stable row identity, provenance, typed unavailable values,
- and per-cohort availability while inheriting the complete result-local
- selection, visualization, workspace, compatibility, and module-budget tree.
- Both implementations enforce the same deterministic scenario boundary:
- exact per-trial provenance, zero shear/turbulence, seed zero, and no gusts.
-- SPEC 1.14.13 is the unique combined child entry. Verification passes 27
- focused Python contract/adapter/selection tests, 1,549 complete
- Rate/shared-swing/golf-club tests with two explicit optional build123d skips,
- and all 556 React tests across 92 files plus type-check/lint/build. Exact-
- parent Ruff/format/pinned MyPy/Bandit, the two-file 500-line budget, docs,
- minimum-test, assertions, detect-secrets, diff, and CPython 3.10 compilation
- pass. Independent re-review found no actionable findings after checking the
- exact provenance derivation and all five deterministic-scenario regressions.
- Protected current-head CI, unresolved threads, and repository review remain
- release gates after publication.
-
-## 2026-08-11 latest #4203 propagation into workspace PR #4279
-
-- PR `#4279` remains on `feat/4218-toolstrip-workspace`, based on
- `feat/4181-launch-monitor-registry`; exact parent
- `0216a547aa79727091a2939b96e779e8ddbd7304` is incorporated by a normal
- two-parent merge without rebase, retarget, force-push, or history rewrite.
-- There are no feature-code conflicts. The child retains its workspace,
- toolstrip, module-visibility, navigation, granular playback, and independent
- plot behavior while inheriting the parent's pinned formatting and
- identity-preserving 222/205/131-line kinetics split.
-- Preserve both append-only histories below. Fresh merged-tree protected CI,
- required review, unresolved-thread checks, and dependency order remain
- release gates; this local merge is not a completion or publication claim.
-
-## 2026-08-10 Second #4203 propagation into workspace PR #4279
-
-- PR `#4279` remains the immediate child on
- `feat/4218-toolstrip-workspace`, based on
- `feat/4181-launch-monitor-registry`.
-- Exact repaired parent head
- `12dd76a8dbcc106c4683f2f2e53076f8dc6f1b76` is incorporated through a
- normal merge commit; no feature code conflicts and no branch or PR topology
- is rewritten.
-- Preserve both append-only handoff histories. Fresh child protected CI,
- review, and earlier dependency gates remain required.
-- Post-reconciliation evidence is 25 focused D-plane/impact tests plus docs
- governance, changed-file-size, and whitespace gates.
-
-## 2026-08-10 Exact #4203 propagation into workspace PR #4279
-
-- PR `#4279` remains the immediate child on branch
- `feat/4218-toolstrip-workspace`, based on
- `feat/4181-launch-monitor-registry`.
-- Original child `05383d333b6fd87eaf5e37305476f50b505c2c2e` normally merges
- exact parent `31cbc007d4c85b5479b7cd0fb0969124eab2af67`; preserve that
- two-parent order and do not rebase, retarget, force-push, or change draft
- state.
-- The child workspace/toolstrip, module-visibility, granular playback, path
- trail, and independent plot behavior remain authoritative. The parent
- `ImpactLayerControls`, navigation-state constants, plotting catalog, and
- triple-pendulum extractions are integrated without duplicate state.
-- Verification is green across 1,339 Python tests with six explicit skips, 545
- React tests plus type-check/lint/build, the 40-test post-format PyQt rerun,
- exact-parent Ruff/Ruff-format/Black/pinned MyPy/Bandit, the 500-line budget,
- docs/minimum-test/assertion/detect-secrets/diff gates, real CPython 3.10.20
- compile/import checks, and 30 compatibility regressions. There is no Rust
- delta from the exact parent. Independent staged review found no actionable
- findings after 76 additional focused PyQt/navigation/workspace tests.
- Current-head protected CI, unresolved-thread checks, and required repository
- review remain release gates after guarded publication.
-
-## 2026-08-11 #4203 append-only SPEC preservation repair
-
-- Independent review of local candidate `e20b4f630...` found four exact
- current-parent history rows missing from SPEC: 2026-08-10 versions 1.13.11,
- 1.13.9, 1.13.7, and 1.13.6. The current documentation-only follow-up restores
- those rows verbatim and advances the declared/changelog version together.
-- Runtime files, tests, ordered merge parents, PR base, and validation evidence
- are byte-unchanged. Re-review, normal publication, exact-head protected CI,
- and downstream propagation remain required.
-
-## 2026-08-11 #4203 current-parent reconciliation
-
-- The current D-plane base is exact head
- `f3363aa88868f6a5c7e9ccfc682a9eca014e86c1`; #4203's exact published child
- is `217e36dc93d30f79826847f958fbcd10805e58ed`. They are being composed in
- that order by a normal merge while retaining base `feat/4189-dplane`.
-- The parent's nine changed files merge without semantic conflict except for
- formatting around the inherited kinetics origin offset. The split child
- facade remains authoritative because the obsolete parent expression reaches
- through `source.inner`; the equivalent explanatory comment is preserved.
-- The exact CI-pinned MyPy 1.13 delta found four additional Qt-stub `Any`
- boundaries after the merge. …11026 tokens truncated… PR #4217
-was squash-merged there. It adds one
-UI-neutral registry for 17 File/View/Tools commands, a strict versioned
-workspace document with atomic file persistence, matched PyQt/React top
-toolstrips, persistent module visibility/order, theme and shortcut surfaces,
-and direct Impact/Swing/Flight navigation. File actions that do not yet have a
-complete client adapter remain visibly disabled with a reason rather than
-pretending to save incomplete state.
-
-The same continuation corrects the interaction defects reported against the
-live Swing and Plots views. Playback now has deterministic replay-from-end,
-Restart, granular 0.05x through 4.00x speed, pause, and loop behavior. The
-full swing path is opt-in so a persistent trail does not obscure the current
-frame. Each managed plot now owns a distinct figure/canvas, zoom state,
-Auto Fit action, wheel zoom, and independently movable or hideable legend;
-the plot workspace presents all managed plots instead of reusing one selected
-canvas. PyQt small-window testing caught the new playback editor compressing
-below the 64 px readability floor; the explicit editor minimum fixes that case
-and the three-case layout suite passes.
-
-Two read-only cross-repository audits are now tracked as separate programs:
-
-- [#4260](https://github.com/D-sorganization/Tools/issues/4260), with
- #4261-#4266, establishes one impact/flight authority and a machine-readable
- parity contract across Tools PyQt, Tools React, UpstreamDrift PyQt, and
- UpstreamDrift React.
-- [#4267](https://github.com/D-sorganization/Tools/issues/4267), with
- #4268-#4276, defines qualified landing, bounce, skid, roll, and total-distance
- modeling with editable ground profiles and exact UpstreamDrift adapters.
-
-The parity audit found that UpstreamDrift PyQt reuses Tools, while the
-UpstreamDrift React launcher has no native Rate React route. UpstreamDrift's
-Tools gitlink `ff4240217005e1415ca409fd124e50b64ee642d2` also predates the
-current integration head by 184 commits, and its sibling/vendor resolution is
-ambiguous. The ground audit found a useful existing fail-closed
-`GroundModelResult` boundary plus reusable putting/terrain primitives, but no
-qualified end-to-end ground solver. Before bounce can be correct, airborne
-flight must terminate against physical terrain plus ball radius and preserve
-the full terminal angular-velocity vector; the current relative launch-plane
-event and spin-free trajectory state do neither. Those prerequisites are
-explicit in #4269 and must not be hidden by UI-derived estimates.
-
-The final local verification pass is green. The complete Rate-of-Closure and
-shared swing-model run passed 890 tests with one expected skip because the
-optional `swing_core` Rust wheel is not installed; the remaining 15 warnings
-are the existing Hypothesis collection warning. React passed 89 files / 545
-tests, zero-warning ESLint, TypeScript checking, and the production Vite build.
-Ruff, Black, targeted mypy, `git diff --check`, and the repository structural
-limits also pass: every changed production Python file is at most 400 lines and
-every changed production Python function is at most 50 lines. Rendered PyQt
-inspection confirmed independent plot canvases, responsive single-column
-reflow at the tested desktop width, independent 125%/100% zoom state, working
-Auto Fit, and the opt-in trail/playback controls. These are local validation
-results only; they do not establish protected CI, review, merge, or release
-status.
-
-### 2026-08-07 variation export and completion audit continuation
-
-The post-toolstrip branch `feat/4144-variation-export-continuation` is published
-as [draft PR #4280](https://github.com/D-sorganization/Tools/pull/4280), based
-on exact parent head `c36ca36e91f34fa849d2508708bf9dd6c0cdc392`. It keeps #4279 unchanged
-while closing one remaining #4144 parity gap: selected scalar scatter data can
-now be exported as CSV from both clients, retaining every raw trial, typed
-outcome, and unavailable cell rather than only the finite points drawn on the
-canvas. PyQt also has a bounded read-only raw-trial table matching the web
-workflow, and the table population is shared with the matrix view.
-
-The complete post-change local gates passed:
-
-- Python/PyQt/shared swing suite: `890 passed, 1 skipped, 15 warnings`; the
- skip is the optional `swing_core` wheel and the warnings are the existing
- Hypothesis collection and empty polynomial-preview legend warnings.
-- React: `89` files / `545` tests passed.
-- Ruff check/format, Black, targeted mypy, TypeScript, zero-warning ESLint,
- the `166`-module Vite production build, and `git diff --check` passed.
-- Every changed production file is below 400 lines and every changed
- production function is at most 50 lines.
-
-A live GitHub/source reconciliation covered every requested epic in this
-campaign. No epic yet satisfies its own definition of done: most implementation
-is still on feature branches, #4119 is the only Rate platform PR targeting
-`main` and is currently dirty, #4203 and #4279 remain draft/unstable, and only
-formal club-builder child #4147 is closed. The variation request is
-substantively implemented, but #4142/#4144 remain open because bounded
-large-ensemble execution, nonlinear global sensitivity, localized execution,
-the immutable UpstreamDrift consumer pin, protected CI, and default-branch
-release are incomplete.
-
-The literal universal-runner audit also found two uncovered many-evaluation
-paths. Wind strategy analysis retains all paired outcomes but has no user
-workflow or universal plot adapter; capability optimization retains aggregates
-but not individual sample rows. The next safe model slice is a UI-neutral
-scalar-ensemble contract with unique composite row IDs, unit-bearing variable
-metadata, caller-defined cohorts, paired-finite scatter extraction, and exact
-availability accounting. Wind integration must accept both its immutable
-request and analysis so launch definitions and provenance are not inferred.
-Issue #4199 already owns the required controls, scatter, strategy table,
-progress/cancellation, and export workflow.
-
-The first narrow #4199 implementation slice is published as
-[draft PR #4281](https://github.com/D-sorganization/Tools/pull/4281) from branch
-`feat/4199-wind-scalar-adapter`, stacked on exact PR #4280 head
-`d71b0ea01b5659d3049ff05627c41f06481207e4`. Implementation commit
-`4a28114aa` introduces an exact
-cross-runtime `scalar-ensemble/v1` wire contract and pure wind-strategy
-adapters. The contract preserves structured provenance, unit-bearing variable
-definitions, caller-defined cohorts, RFC3986 composite identities, nullable
-raw rows, and exact scatter availability. The adapters validate the immutable
-request against the stored paired analysis, preserve completed,
-nonconverged, and invalid outcomes, and never invoke a flight model. React has
-an explicit mocked-integrator regression test for that boundary.
-
-Current exact local evidence is 906 Python/PyQt/shared-swing tests passed with
-one expected optional-Rust skip and 15 existing warnings, plus 91 React test
-files / 555 tests passed. Ruff, formatting, Black, focused mypy, TypeScript,
-zero-warning ESLint, the 166-module production build, and `git diff --check`
-passed. The function budget passed, but the 403-line wind adapter did not meet
-the mandatory below-400 module ceiling at that historical head; the
-2026-08-11 repair above corrects that blocker. The adapter is plot-ready model
-infrastructure, not an end-user workflow; #4199 remains open for worker,
-progress/cancellation, client controls, strategy/scatter displays,
-persistence, and exports.
-
-### 2026-08-07 ground and four-surface audit refinement
-
-The rolling-ground and cross-application parity requests remain tracked by the
-existing [ground epic #4267](https://github.com/D-sorganization/Tools/issues/4267)
-and [parity epic #4260](https://github.com/D-sorganization/Tools/issues/4260);
-no duplicate epic or child issue is required. The latest exact-path audit and
-acceptance refinements are attached to
-[the ground epic](https://github.com/D-sorganization/Tools/issues/4267#issuecomment-5222725556)
-and [the parity epic](https://github.com/D-sorganization/Tools/issues/4260#issuecomment-5222726010).
-
-The scientific implementation order is contractual: #4268 defines the
-surface/contact/trajectory/result transfer state, then #4269 corrects physical
-terrain contact and preserves terminal full angular velocity. Only then may
-#4270/#4271 qualify the 3D impulse, repeated bounce, skid, and pure-roll
-phases. Carry remains first physical contact. Final downrange, final lateral,
-horizontal displacement, surface path length, and launch-monitor-style total
-distance are distinct quantities; no implementation may silently assume
-`total distance = carry + roll distance`.
-
-Reusable UpstreamDrift scope is deliberately narrow: its split terrain
-material/elevation/normal/region package can feed a one-way versioned DTO
-adapter. Current scalar landing, heuristic putting-roll, duplicate legacy
-terrain, and Rust tangential-loss implementations are reference material, not
-the qualified physics authority. Upstream surface defaults remain illustrative
-until citations, calibration, uncertainty, and applicability are recorded.
-
-The parity matrix must distinguish seven product identities: standalone Rate
-PyQt6 and React, the Upstream Rate PyQt provider and React route, Upstream Shot
-Tracer PyQt6 and React, and the legacy Upstream ball-flight GUI. Current
-Upstream `main` (`0782853295e005af68818617e4725eb980890f43`) pins Tools at
-`ff4240217005e1415ca409fd124e50b64ee642d2`, exposes no native Rate React route,
-and contains contradictory vendor-first and sibling-first Tools resolvers.
-These facts are current audit evidence, not completion; #4260, #4267, and all
-children remain open.
-
-## 2026-08-10 PR #4202 D-plane ndarray typing repair
-
-- The repair is based on exact published PR `#4202` head
- `b443fdbed7064c5db0320106013c8413e3e24356` and retains base
- `feat/4162-wedge-impact-visualization`.
-- CI Standard run `31384810375`, job `93442745760`, reported two pinned MyPy
- 1.13 `no-any-return` errors in private NumPy conversion/projection helpers.
- Explicit ndarray local boundaries resolve those errors without changing
- geometry, validation, frames, serialized contracts, or UI behavior.
-- RED/GREEN evidence is exact: two errors reproduced before the edit and zero
- afterward. Twenty-four focused D-plane/impact tests, seven metadata/pre-push
- contract tests, scoped Ruff/Ruff-format/Black, docs governance, minimum-test,
- module-size, changed-file-size, and diff checks pass. Three exploratory
- CI-workflow contract tests retain unrelated older-branch toolcache/env drift;
- no workflow file is changed here.
-- This repair does not alter the stacked base, publish the branch, change its
- draft state, or authorize a merge. Parent-first ordering, protected CI, and
- review remain required.
-
-## 2026-08-10 Propagation into 3D D-plane geometry
-
-- Immediate child PR `#4202` keeps base
- `feat/4162-wedge-impact-visualization`.
-- Its original head `b4abec03bccfbdd87ddf91427159c5c2332c21dd`
- normally merges exact parent `#4179` head
- `6704a3e541a3e74c28b4a284530d1a21269dd340`; no branch rewrite, retarget, or
- force push is permitted.
-- The Python 3.10 UTC repair and AST guard are inherited alongside the typed,
- frame-explicit D-plane, spin-loft, visualization, and export contracts.
-- Persisted D-plane layer controls are extracted into a focused helper so the
- simulation view satisfies the protected 500-line module budget without a
- behavior or compatibility-seam change.
-- Combined-stack verification is green: 93 focused and 825 scoped Python tests
- (two optional `build123d` skips), 360 React tests and all web gates, real
- CPython 3.10.20 compilation/UTC, scoped Ruff/Black/MyPy, and repository
- governance gates. The exact parent's 12 unchanged `swing-core` tests remain
- applicable because this child has no Rust delta. The inherited 17-error broad
- MyPy Qt/NumPy baseline in 11 untouched files remains outside scope.
- Protected CI and required review remain release gates.
-
-## 2026-08-10 Propagation into wedge impact visualization
-
-- Immediate child PR `#4179` keeps base `feat/4166-wedge-turf-physics`.
-- Its original head `0eb804e70887c788421332369e42792411aff55a`
- normally merges exact parent `#4178` head
- `bfa83aedc88ead380babc73a699377d98b971006`; no branch rewrite, retarget, or
- force push is permitted.
-- The Python 3.10 UTC repair and AST guard are inherited alongside the
- exact-event, locked-scale, exportable impact-scene contract.
-- Combined-stack verification is green: 58 focused and 739 scoped Python tests
- (two optional `build123d` skips), 347 React tests and all web gates, real
- CPython 3.10.20 compilation/UTC, scoped Ruff/Black/MyPy, and repository
- governance gates. The exact parent's 12 unchanged `swing-core` tests remain
- applicable because this child has no Rust delta. The inherited 17-error broad
- MyPy Qt/NumPy baseline in 11 untouched files remains outside scope.
- Protected CI and required review remain release gates.
-
-## 2026-08-10 Propagation into wedge turf physics
-
-- Immediate child PR `#4178` keeps base `feat/4161-wedge-ground-clearance`.
-- Its original head `aaae3f73e17dbfaad5cca1dc6f49559b3aebe9d5`
- normally merges exact parent `#4174` head
- `9ea93e92563280ec34bca682ad44d7409edd7a02`; no branch rewrite, retarget, or
- force push is permitted.
-- The Python 3.10 UTC repair and AST guard are inherited alongside the passive,
- provenance-gated turf-contact model and explicit force-coupling boundary.
-- Combined-stack verification is green: 56 focused and 732 scoped Python tests
- (two optional CAD-dependency skips), real CPython 3.10.20 checks, scoped
- static analysis, and repository governance gates. With no web or Rust delta,
- the exact parent's green 345 React and 12 Rust tests remain applicable. The
- inherited 17-error broad MyPy Qt/NumPy baseline in 11 untouched files remains
- outside scope.
-
-## 2026-08-10 Propagation into wedge ground clearance
-
-- Immediate child PR `#4174` keeps base `feat/4163-impact-inspector`.
-- Its original head `880a6465fc872cf3d6650283db154ddc41793a31`
- normally merges exact parent `#4173` head
- `9ddaff3b6bca542fd7a2befc7d7b0ae53910a60a`; no branch rewrite, retarget, or
- force push is permitted.
-- The Python 3.10 UTC repair and AST guard are inherited alongside the swept
- wedge ground-clearance model, persistence, PyQt, and React surfaces.
-- Combined-stack verification is green: 56 focused and 703 scoped Python tests
- (two optional CAD-dependency skips), 345 React tests and all web gates, 12
- Rust tests, real CPython 3.10.20 checks, scoped static analysis, and
- repository governance gates. The inherited 17-error broad MyPy Qt/NumPy
- baseline in 11 untouched files remains outside scope.
-
-## 2026-08-10 Propagation into impact inspector
-
-- Immediate child PR `#4173` keeps base `feat/4144-variation-visualizations`.
-- Its original head `3c43955aaeb3964ff8c3ef2748d626baae518b76`
- normally merges exact parent `#4167` head
- `22b66b560652b78de84141344c4ddd9a92a83b26`; no branch rewrite, retarget, or
- force push is permitted.
-- The Python 3.10 UTC compatibility repair and its AST guard are inherited
- additively alongside the existing shared wedge impact-inspector contract.
-- Combined-stack verification is green: 63 focused and 562 total Rate Python
- tests; 334 React tests plus type-check, lint, and production build; 12 Rust
- tests; real CPython 3.10.20 compile/UTC checks; scoped static analysis and
- repository governance gates. The broad MyPy sweep retains 17 pre-existing
- Qt/NumPy typing findings in 11 untouched files. Current-head protected CI and
- required review remain pending release evidence.
-
-## Dependency position
-
-PR `#4167` (`feat/4144-variation-visualizations`) is the base-most open Rate
-feature above the already merged `feat/investigation-suite` carrier. Later
-wedge, D-plane, launch-monitor, workspace, wind, capability, and ground work
-depends on this line and must receive any repair through ordinary parent
-propagation; child branches must not be rewritten.
-
-## 2026-08-10 Python 3.10 repair
-
-- Protected CI at exact pre-repair head
- `edaa56358a9ccf47809533fcab28e6415b336771` collected 13 Rate test modules
- unsuccessfully because `datetime.UTC` does not exist on Python 3.10.
-- The torque-profile controller now consumes the repository's existing
- `shared.python.compatibility.UTC` export.
-- A source-tree AST guard rejects future direct imports and unaliased or
- aliased `datetime.UTC` module-attribute access anywhere under
- `src/rate_of_closure`.
-- Local evidence is green: 27 focused controller/history/AST tests and the
- complete 554-test Rate suite on Python 3.13; real CPython 3.10.20 compatibility
- import; Ruff check/format; focused pinned MyPy 1.13; detect-secrets;
- touched-file size and diff checks.
-
-## Truthful release state
-
-This is an actionable compatibility repair, not completion of issue `#4144` or
-the variation epic. Current-head protected CI, required review, dependency
-propagation, and ordinary merges remain required. Runner download timeouts,
-missing toolcache/link libraries, cancelled jobs, and queued jobs are tracked
-as infrastructure and are never counted as green evidence.
-
-Every implementation commit must update this file, both other canonical
-handoffs, and `SPEC.md`, or explicitly record no material handoff change and
-the reason.
-
-## 2026-08-11 additional parent sections preserved during #4282 reconciliation
-
-## 2026-08-09 PR #4279 Python 3.10 compatibility completion
-
-Exact corrected #4203 parent
-`08a2fdd8ce6bbc8fbb8f121927a677d4addb6b11` is incorporated into #4279 by
-normal local merge `a340fabefa443d47325c5538f342683b38c01ade`; the stack base is
-unchanged and nothing was rebased, retargeted, force-pushed, or published.
-The two child-owned string-enum modules and child workspace UTC validator now
-use the existing shared Python 3.10 compatibility contract at runtime. Native
-enum typing remains explicit under `TYPE_CHECKING`, and wire IDs, schemas,
-timestamp serialization, physics, and UI behavior are unchanged.
-
-The reconciled test covers nine `StrEnum` runtime imports, both `UTC` runtime
-imports, and direct execution of all three child workspace modules. Python
-3.11 passes `126` focused tests. Real CPython 3.10.20 passes all `14`
-compatibility cases and imports 10 dotted Rate/shared targets. Ruff
-check/format and pinned mypy 1.13 pass all affected files; documentation
-governance and diff checks are required in the same commit. Protected CI,
-review, publication, and normal propagation to #4280 and later descendants
-remain outstanding.
-
-## 2026-08-09 PR #4279 parent propagation
-
-The #4279 continuation remains based on `feat/4181-launch-monitor-registry` and
-now contains exact parent head
-`08a2fdd8ce6bbc8fbb8f121927a677d4addb6b11` through a normal merge. Source
-changes applied cleanly; the overlapping handoff/specification histories were
-reconciled monotonically. The result retains the parent's Linux-safe facade
-and Python 3.10 compatibility contracts plus the child's workspace,
-top-toolstrip, module-navigation, playback, and independent plot controls. No
-branch was rebased, retargeted, force-pushed, or published by this continuation.
-
-Current focused evidence is `126 passed` for both facade modules and all
-Python/PyQt tests changed by #4279, plus `8 React files / 32 tests passed` for
-the matching workspace surfaces. Ruff check/format is clean across all 28
-relevant Python files. CI-pinned mypy 1.13 is clean across the 18 changed
-production files and both facade tests after making the child's
-`legend_visible()` Qt boundary return an explicit `bool`. Documentation
-governance, staged/unstaged diff checks, and the affected `29`-test simulation
-GUI rerun pass. Protected CI, review, and publication remain separate release
-requirements.
-
-## 2026-08-09 Python 3.10 compatibility follow-up
-
-The descendant Python 3.10 lane revealed seven unconditional
-`enum.StrEnum` imports already present at PR #4203. The earliest owning parent
-now routes runtime imports through `shared.python.compatibility.StrEnum` while
-using the stdlib type only under `TYPE_CHECKING`. The change preserves every
-enum value and schema while removing the Python 3.11-only import boundary.
-Local evidence is 64 focused contract/physics/compatibility tests, Ruff and
-format, pinned mypy 1.13 across eight changed files, and a real CPython 3.10.20
-probe of the shared fallback and seven module import declarations. Parent is
-published at exact head `ab7de5a47977417e02926c3fbc7476002e82b690`;
-propagate it through #4279, #4280, #4281, and #4282 before retrying descendants.
-
-The same scan found one parent-owned `datetime.UTC` import in the PyQt torque
-profile controller. It now consumes the established compatibility constant,
-preserving UTC serialization while allowing Python 3.10 collection. This
-follow-up belongs on #4203 before the child stack is propagated.
-
-## 2026-08-09 Launch-registry parent CI repair
-
-The earliest campaign parent, draft PR #4203, remains based on
-`feat/4189-dplane` at exact published head
-`912ebc9d69b05763a76c2c8f198d943737e2d3fb`. CI run `31199764932` passed its
-quality gate, then all Python versions failed before assertions because pytest
-collected the flight and solver contract modules through `src.shared...` while
-their absolute dotted facade aliases requested the editable `shared...`
-namespace. The scoped repair converts only those two test imports to relative
-package imports. Production APIs and physics are unchanged. The same run's
-Rust failure is the known runner inability to link `-lpython3.11`. Validate
-the two contract modules under importlib collection, publish a new exact head,
-and propagate it through #4279, #4280, #4281, and #4282 in normal order.
-Both modules now pass all `12` tests on Windows and WSL Python 3.11 with
-importlib collection. Ruff check/format and pinned mypy 1.13 are clean. A
-test-only `Any` cast keeps frozen-dataclass metadata introspection explicit
-without weakening the runtime contract.
diff --git a/docs/release/rate_of_closure_campaign.v1.json b/docs/release/rate_of_closure_campaign.v1.json
index 1f60a6630..133582e1f 100644
--- a/docs/release/rate_of_closure_campaign.v1.json
+++ b/docs/release/rate_of_closure_campaign.v1.json
@@ -134,7 +134,7 @@
"pr": 4282,
"branch": "feat/4199-wind-workflow",
"base_branch": "feat/4199-wind-scalar-adapter",
- "head_sha": "b2baf6ef615b0d756a86ac4ca7eef2fc583210ee",
+ "head_sha": "18fe89201d657116bbca99922297c14968356c44",
"state": "open",
"merge_commit_sha": null,
"protection_evidence": "not_recorded"
@@ -154,7 +154,7 @@
"pr": 4285,
"branch": "feat/4268-ground-contract",
"base_branch": "feat/4197-capability-observer",
- "head_sha": "584e4e53a7990053a346938c4e45538786887ec7",
+ "head_sha": "6a2bc9d06f6f9a28a0d615b19d2ed4fc13871059",
"state": "open",
"merge_commit_sha": null,
"protection_evidence": "not_recorded"
@@ -164,7 +164,7 @@
"pr": 4288,
"branch": "feat/4269-flight-ground-transfer",
"base_branch": "feat/4268-ground-contract",
- "head_sha": "c39297d37a17d5d8d3520ed62c5563cdcc609cab",
+ "head_sha": "4972e55e0bb6e5b6bf7da0f899eed5d4f54e7d9d",
"state": "open",
"merge_commit_sha": null,
"protection_evidence": "not_recorded"
@@ -194,7 +194,7 @@
"pr": 4302,
"branch": "feat/4270-ground-impact-bounce",
"base_branch": "feat/4269-flight-ground-transfer",
- "head_sha": "62beb3e1aa951645fd556a53f9cbae4bb46c47e5",
+ "head_sha": "cf6e72bad98e5f36f782254942e6895b8b71e670",
"state": "open",
"merge_commit_sha": null,
"protection_evidence": "not_recorded"
@@ -204,7 +204,7 @@
"pr": 4304,
"branch": "feat/4271-ground-skid-roll",
"base_branch": "feat/4270-ground-impact-bounce",
- "head_sha": "3f861c1faaa7455faee92eaa7f813174667208e0",
+ "head_sha": "0ea6740965068542e9d8c7449e06ec07d88969e0",
"state": "open",
"merge_commit_sha": null,
"protection_evidence": "not_recorded"
@@ -214,7 +214,7 @@
"pr": 4332,
"branch": "feat/4271-regional-surface-transitions",
"base_branch": "feat/4271-ground-skid-roll",
- "head_sha": "5ac3c1f233de30dd42eeac57073cbdb149bde652",
+ "head_sha": "04ccf08dd990de1cd056a3420e67772773a4be2e",
"state": "open",
"merge_commit_sha": null,
"protection_evidence": "not_recorded"
@@ -224,7 +224,7 @@
"pr": 4335,
"branch": "feat/4271-regional-wire-contract",
"base_branch": "feat/4271-regional-surface-transitions",
- "head_sha": "8f933ed8dcb29e55ece4ec6bb1e60813f6794d57",
+ "head_sha": "9e01ccc3e891cc45907293751a192624195a77a5",
"state": "open",
"merge_commit_sha": null,
"protection_evidence": "not_recorded"
@@ -234,7 +234,17 @@
"pr": 4339,
"branch": "feat/4274-regional-surface-ui",
"base_branch": "feat/4271-regional-wire-contract",
- "head_sha": "d21741e312b849a63f73cabf351a15d9de80fb94",
+ "head_sha": "db335937afc4b587d235eb705e315f577519c5e6",
+ "state": "open",
+ "merge_commit_sha": null,
+ "protection_evidence": "not_recorded"
+ },
+ {
+ "id": "pr-4342",
+ "pr": 4342,
+ "branch": "feat/4274-regional-plan-io",
+ "base_branch": "feat/4274-regional-surface-ui",
+ "head_sha": "c1f47f2ef68b3db102da5416aaac17a40f675207",
"state": "open",
"merge_commit_sha": null,
"protection_evidence": "not_recorded"
@@ -423,6 +433,42 @@
"src/rate_of_closure/AGENT_HANDOFF.md",
"docs/development/RATE_OF_CLOSURE_CAMPAIGN_HANDOFF.md"
]
+ },
+ {
+ "id": "ground-regional-ui-helper-local-d217",
+ "kind": "local",
+ "commit_sha": "d21741e312b849a63f73cabf351a15d9de80fb94",
+ "outcome": "passed",
+ "commands": [
+ "python -m pytest tests/rate_of_closure/test_regional_surface_plan.py tests/rate_of_closure/test_gui.py tests/rate_of_closure/test_layout_minsize.py -q",
+ "npm test -- --run",
+ "npm run type-check && npm run lint && npm run build",
+ "uvx --from ruff==0.14.10 ruff check src/rate_of_closure tests/rate_of_closure && uvx --from ruff==0.14.10 ruff format --check src/rate_of_closure tests/rate_of_closure"
+ ],
+ "summary": "The current PR #4339 parent passed focused Python/PyQt and React qualification plus the complete 672-test React suite after replacing its six-parameter number-input helper with a frozen specification and three-parameter helper. This remains local evidence, not protected release evidence.",
+ "source_paths": [
+ "AGENT_HANDOFF.md",
+ "src/rate_of_closure/AGENT_HANDOFF.md",
+ "docs/development/RATE_OF_CLOSURE_CAMPAIGN_HANDOFF.md"
+ ]
+ },
+ {
+ "id": "ground-regional-io-local-8e1c",
+ "kind": "local",
+ "commit_sha": "8e1c7ccd99a7c4886c5fb9ccc7e4d94a6d7e3833",
+ "outcome": "passed",
+ "commands": [
+ "python -m pytest tests/rate_of_closure/test_regional_surface_plan.py tests/rate_of_closure/test_regional_surface_plan_io.py tests/rate_of_closure/test_workspace_files.py -q",
+ "npm test -- --run src/components/RegionalSurfacePlanPanel.test.tsx",
+ "npm run type-check && npm run lint && npm run build",
+ "uvx --from ruff==0.14.10 ruff check src/rate_of_closure tests/rate_of_closure && uvx --from ruff==0.14.10 ruff format --check src/rate_of_closure tests/rate_of_closure"
+ ],
+ "summary": "The published PR #4342 child passed strict native atomic and bounded browser regional request I/O qualification, safe-number parity, bounded UTF-8 import, static analysis, build, and governance gates before parent reconciliation. Fresh protected evidence remains open.",
+ "source_paths": [
+ "AGENT_HANDOFF.md",
+ "src/rate_of_closure/AGENT_HANDOFF.md",
+ "docs/development/RATE_OF_CLOSURE_CAMPAIGN_HANDOFF.md"
+ ]
}
],
"programs": [
@@ -1204,7 +1250,8 @@
"pr-4304",
"pr-4332",
"pr-4335",
- "pr-4339"
+ "pr-4339",
+ "pr-4342"
],
"supported_surfaces": {
"tools.pyqt6": "implemented_unverified",
@@ -1217,14 +1264,16 @@
"ground-skid-roll-local-f475",
"ground-regional-local-1a48",
"ground-regional-wire-local-74a0",
- "ground-regional-ui-local-cbb9"
+ "ground-regional-ui-local-cbb9",
+ "ground-regional-ui-helper-local-d217",
+ "ground-regional-io-local-8e1c"
],
- "evidence_gap": "The contract, flight-transfer, impact/bounce, static-plane skid/roll, regional-surface, regional-plan wire, and regional-editor carriers remain open on draft PRs 4285, 4288, 4302, 4304, 4332, 4335, and 4339. Exact local evidence exists, but fresh protected evidence for the reconciled heads, execution/playback, result interchange, workspace model-input persistence, changing geometry, compiled-runtime physics, and downstream parity remain absent.",
+ "evidence_gap": "The contract, flight-transfer, impact/bounce, static-plane skid/roll, regional-surface, regional-plan wire, regional-editor, and regional request-I/O carriers remain open on draft PRs 4285, 4288, 4302, 4304, 4332, 4335, 4339, and 4342. Exact local evidence exists, but fresh protected evidence for the reconciled heads, execution/playback, result interchange, workspace model-input persistence, measured calibration, changing geometry, compiled-runtime physics, and downstream parity remain absent.",
"limitations": [
"Airborne flight must first terminate against physical terrain and preserve terminal angular velocity.",
"Current UpstreamDrift terrain and putting implementations are reference inputs rather than the qualified authority.",
"The #4270 rigid impact law does not consume firmness, grass, compressibility, moisture, or rolling-resistance fields.",
- "Published open PR #4304 qualifies one immutable planar profile and optional finite tangent-axis edge; open PR #4332 adds bounded coplanar material overlays; open PR #4335 adds a strict Python/TypeScript plan wire boundary and Python resolver; and open PR #4339 adds matched session-only PyQt6/React request editors. Changing normals, height or velocity discontinuities, terrain deformation, torsional-spin damping, roll-to-skid transitions, internal transition-ledger export, execution/playback, result interchange, measured calibration, workspace model-input persistence, compiled or TypeScript regional physics, and downstream adapters remain unimplemented."
+ "Published open PR #4304 qualifies one immutable planar profile and optional finite tangent-axis edge; open PR #4332 adds bounded coplanar material overlays; open PR #4335 adds a strict Python/TypeScript plan wire boundary and Python resolver; open PR #4339 adds matched PyQt6/React request editors; and open PR #4342 adds editor-qualified canonical request import/export with native atomic semantics and explicit browser limitations. Changing normals, height or velocity discontinuities, terrain deformation, torsional-spin damping, roll-to-skid transitions, internal transition-ledger export, execution/playback, result interchange, measured calibration, workspace model-input persistence, compiled or TypeScript regional physics, and downstream adapters remain unimplemented."
],
"depends_on_issues": [
4191
diff --git a/docs/specs/GROUND_SKID_ROLL.md b/docs/specs/GROUND_SKID_ROLL.md
index c8b7e1a28..1e39b2750 100644
--- a/docs/specs/GROUND_SKID_ROLL.md
+++ b/docs/specs/GROUND_SKID_ROLL.md
@@ -203,11 +203,23 @@ schema, unit, provenance, and request readback.
The regional v1 wire schema has no calibration record, so the editor does not
invent one or widen that schema. `unvalidated` is explicit presentation/source
-qualification and is included in the source digest. This first slice is
-session-only: current web workspace file commands do not persist model inputs,
-and neither client claims request export/import, execution, result playback,
-or measured-course calibration. Those capabilities require separate contracts
-and acceptance evidence.
+qualification and is included in the source digest. PyQt6 native Open/Save As
+and React browser import/download persist only the canonical regional request;
+workspace model-input persistence remains a separate contract. Import is
+transactional and accepts only the editor producer/provider v1, fixed qualified
+axis/geometry, and editor row capacity. An unchanged import retains the exact
+request and provenance; editing rebinds the draft digest. Browser downloads
+cannot promise a native path, atomic replacement, or recent-file access.
+Wire numbers are bounded to the shared cross-runtime safe range. Native
+precedence entry preserves every nonnegative integer through
+9,007,199,254,740,991 exactly, so a qualified import cannot be silently narrowed
+before validation or Save As.
+Native import reads one binary handle with a one-byte overflow sentinel before
+strict UTF-8 decoding, so mutable files cannot bypass the 1 MiB allocation cap
+between a metadata check and content parsing.
+Neither client claims execution, result playback, or measured-course
+calibration. Those capabilities require separate contracts and acceptance
+evidence.
Skid and roll distances are accumulated separately from centre speed relative
to the moving surface. Collinear constant-acceleration segments use the exact
diff --git a/src/rate_of_closure/AGENT_HANDOFF.md b/src/rate_of_closure/AGENT_HANDOFF.md
index 52a1d5c5f..d858b22d7 100644
--- a/src/rate_of_closure/AGENT_HANDOFF.md
+++ b/src/rate_of_closure/AGENT_HANDOFF.md
@@ -1,5 +1,38 @@
# AGENT_HANDOFF — rate_of_closure
+## 2026-08-11 PR #4342 current-parent propagation candidate
+
+This local no-publish merge keeps `feat/4274-regional-plan-io` over
+`feat/4274-regional-surface-ui`. Exact current child
+`c1f47f2ef68b3db102da5416aaac17a40f675207` is the first parent and exact
+reviewed local #4339 candidate `db335937afc4b587d235eb705e315f577519c5e6`
+is the second parent. Child-owned canonical request import/export, bounded UTF-8,
+native atomic save, browser-qualified download, tests, and limitations remain
+intact while inheriting current editor, wire, regional physics, and complete
+ground ancestry.
+
+The default shared canonical encoder continues to reject floats and integers
+outside JavaScript's safe range. Only the capability-observation facade selects
+a separately named extended finite-float policy. It shares the same recursive
+encoder, retains safe-range integer checks, emits exact exponent-free `1e20`
+and `1e21` tokens matching TypeScript, and rejects non-finite values.
+
+Local qualification passes all `909` Rate-of-Closure Python tests, all `110`
+React files / `686` tests, the complete Cargo workspace, `47` focused Python
+compatibility/regional-I/O tests, and `12` focused React capability tests.
+Pinned Ruff 0.14.10 check/format passes `17` changed Python files; pinned MyPy
+1.13 and Bandit pass `12` changed production files. TypeScript, zero-warning
+ESLint, the 199-module Vite build, Rust format/warning-denied clippy, 400- and
+500-LOC gates, manifest/docs/blocking-gate/assertion/minimum-test governance,
+marker scans, and diff checks pass. One untouched manual-delivery UI test timed
+out in the first concurrent full run, then passed alone and in the single
+complete rerun.
+
+The candidate is not published or released. Execution/playback, result
+interchange, measured calibration, persistence, changing geometry or velocity,
+TypeScript/compiled regional physics, downstream parity, protected exact-head
+evidence, review, approval, dependency integration, and release remain open.
+
## 2026-08-11 PR #4339 current-parent propagation candidate
This local no-publish merge keeps `feat/4274-regional-surface-ui` over
@@ -28,184 +61,16 @@ interchange, measured calibration, persistence, changing geometry or velocity,
TypeScript/compiled regional physics, downstream parity, protected exact-head
evidence, review, approval, dependency integration, and release remain open.
-## 2026-08-11 PR #4339 structural helper repair candidate
-
-This local follow-up descends exact independently reviewed reconciliation
-candidate `eedad6d23b517eb4c99d4ba9000ff6555101099f`. Independent review found
-one publication blocker: the regional PyQt number-input helper accepted six
-parameters, above the campaign's mandatory four-parameter limit. RED-first
-tests now bind the helper's signature and all observable widget settings. A
-frozen `NumberInputSpec` validates finite positive step and finite ordered
-bounds before widget construction; the three-parameter helper preserves field
-names, values, units, ranges, increments, tooltips, and presentation order.
-
-Eight focused Python/PyQt tests and 25 focused React tests pass; the complete
-React suite passes all 108 files / 672 tests. Pinned Ruff check/format, MyPy on
-all six affected production modules, Bandit medium/high screening, TypeScript,
-zero-warning ESLint, documentation/manifest governance, changed-production,
-test-assertion, minimum-test, 500-LOC, and diff gates pass. Mandatory maxima
-are 400 module lines, 42 function lines, and three parameters. A broader
-Rate-of-Closure Python run reached the ten-minute workstation lifecycle bound
-without yielding an assertion failure; it is not counted as passing evidence.
-The monorepo-wide lane separately exposed unrelated baseline failures and
-xdist worker termination. No schema, digest, regional physics, UI behavior,
-PR base, protected evidence, or release boundary changes.
-
-## 2026-08-11 PR #4339 current-parent ancestry candidate
-
-The clean `feat/4274-regional-surface-ui` worktree normally merges exact
-published child `cbb9c0a6bdc6a50f59f7a661139b9d53e1892980` with exact newly
-published #4335 parent `9e01ccc3e891cc45907293751a192624195a77a5`,
-without changing #4339's base. The accessible PyQt6/React editors and strict
-invalidation behavior remain intact alongside the parent's wire, resolver,
-regional-physics, and complete ground ancestry. Execution/playback, result
-interchange, persistence, compiled physics, downstream parity, protected
-evidence, integration, and release remain open.
-
-## 2026-08-10 PR #4339 stale-validation invalidation follow-up
-
-Rendered exact-head browser QA found that a validated one-overlay readback
-remained visible after adding a second overlay. The broad PyQt6 suite also
-found missing hover hints on the new controls. PyQt6 and React now clear both
-canonical readback and prior validation state whenever any identity, interval,
-material, or overlay-row draft value changes; PyQt6 exposes the explicit
-"Changes not validated" pending state, and every PyQt6 interactive has a
-specific engineering-context tooltip. RED-first regression tests cover the
-dynamic-row path on both surfaces. Final local evidence is 870 Python/PyQt
-tests and 672 React tests passing; Ruff, format, MyPy, TypeScript, zero-warning
-ESLint, the 198-module production build, manifest/docs/file-size governance,
-and diff checks are clean. The known polynomial-generator empty-legend warning
-is unrelated. This changes no wire schema, provenance digest, physics, or
-persistence boundary; fresh protected CI is still required before merge.
-
-## 2026-08-11 Regional wire receives current regional-surface parent
-
-Open draft PR `#4335` retains `feat/4271-regional-wire-contract` over
-`feat/4271-regional-surface-transitions`. Exact remote regional-wire child
-`9e01ccc3e891cc45907293751a192624195a77a5` is merged first and exact current
-regional-surface parent `5ac3c1f233de30dd42eeac57073cbdb149bde652`
-second by an ordinary no-ff merge. Child-owned wire production, schemas,
-tests, canonical fixture evidence, resolver binding, and limitations remain
-intact while inheriting current regional, skid/roll, impact/bounce,
-flight-transfer, and strict-ground ancestry.
-
-Focused local qualification passes all `132` Python ground/regional-wire tests,
-`9` focused React regional/ground-contract tests, and all `137` `tools-core`
-Rust tests. TypeScript, zero-warning ESLint, the 190-module Vite build, Rust
-format and warning-denied clippy, pinned Ruff 0.14.10 across six changed Python
-files, pinned MyPy 1.13 and Bandit medium/high across four production files,
-the 500-LOC changed-file gate, manifest validation plus eight contracts,
-documentation governance, exact wire-tree preservation, history/marker, and
-diff checks are green.
-
-This candidate remains unpublished and `not_released`. Changing geometry or
-velocity, internal transition-ledger export, regional UI, compiled or
-TypeScript regional physics, UpstreamDrift parity, protected exact-head CI,
-review, approval, dependency integration, and release remain open.
-
-## 2026-08-11 Regional surfaces receive current skid/roll parent
-
-Open draft PR `#4332` retains
-`feat/4271-regional-surface-transitions` over
-`feat/4271-ground-skid-roll`. Exact remote regional-surface child
-`04ccf08dd990de1cd056a3420e67772773a4be2e` is merged first and exact current
-skid/roll parent `3f861c1faaa7455faee92eaa7f813174667208e0` second by an ordinary no-ff
-merge. Child-owned regional transition production, tests, fixtures, contracts,
-evidence, and limitations remain intact while inheriting current skid/roll,
-impact/bounce, flight-transfer, and strict-ground ancestry.
-
-Focused local qualification passes all `121` Python ground/regional tests,
-`20` focused React ground-contract/transfer tests, and all `137` `tools-core`
-Rust tests. TypeScript, zero-warning ESLint, the 189-module Vite build, Rust
-format and warning-denied clippy, pinned Ruff 0.14.10 across 14 changed Python
-files, pinned MyPy 1.13 and Bandit medium/high across 12 production files, the
-500-LOC changed-file gate, manifest validation plus eight contracts,
-documentation governance, exact child-tree preservation, history/marker, and
-diff checks are green.
-
-This candidate remains unpublished and `not_released`. Changing normals,
-discontinuous geometry or surface velocity, regional UI, compiled regional
-physics, UpstreamDrift parity, protected exact-head CI, review, approval,
-dependency integration, and release remain open.
-
-## 2026-08-11 Skid/roll receives current impact/bounce parent
-
-Open draft PR `#4304` retains `feat/4271-ground-skid-roll` over
-`feat/4270-ground-impact-bounce`. Exact remote skid/roll child
-`0ea6740965068542e9d8c7449e06ec07d88969e0` is merged first and exact current
-impact/bounce parent `62beb3e1aa951645fd556a53f9cbae4bb46c47e5`
-second by an ordinary no-ff merge. Child-owned skid/roll production, contracts,
-tests, fixture, and limitations remain intact while inheriting current impact,
-flight-transfer, and strict-ground ancestry.
-
-Local verification passes `154` focused ground/flight tests, all eight manifest
-tests, and all `137` `tools-core` Rust tests. Pinned Ruff 0.14.10 covers the 18
-PR-delta Python files; pinned MyPy 1.13 and Bandit medium/high cover 12
-production files. Rust format/clippy, manifest, docs, exact child-tree,
-history/marker, and diff gates are green.
-
-This local model slice remains `not_released`. Regional/changing-normal
-surfaces, deformation, torsional damping, roll-to-skid transitions, UI,
-compiled physics, publication, protected exact-head CI, review, approval,
-downstream integration, and release remain open.
-
-## PR #4302 corrected-flight-transfer propagation
-
-Exact corrected #4288 parent
-`247215422a6d4b677552955b4923bc609a553259` is incorporated into
-`feat/4270-ground-impact-bounce` by the normal merge containing this handoff.
-PR #4302 keeps base `feat/4269-flight-ground-transfer`; neither branch was
-rebased, retargeted, rewritten, or force-pushed. The child retains passive
-impact, deterministic repeated hops, exact contact, capture-to-skid, bounded
-cancellation/failure, and airborne evidence while inheriting corrected flight
-transfer, deterministic workspace timestamps, and canonical `swing_sim`
-identity.
-
-This remains a partial `not_released` slice. Issue #4271 retains skid, roll,
-rest, total distance, and final ground results; terrain deformation, UI,
-TypeScript bounce physics, compiled bounce runtimes, and UpstreamDrift adapters
-remain excluded. Protected CI, independent review, and normal stack collapse
-remain open.
-Merged-tree validation is `987` Python tests, `106` React files / `661` tests,
-and the complete `tools-core` Rust suite at `137` tests (`111` unit, `20`
-transfer, `6` wire). The affected cross-version suite is also `146` tests on
-real CPython 3.10.20. The 189-module Vite production build, TypeScript,
-zero-warning ESLint, Ruff check/format across 90 files, pinned mypy 1.13 across
-all 17 ground and nine transfer production modules, Rust workspace format plus
-warning-denied `tools-core` clippy, campaign-manifest validator plus eight
-contracts, documentation governance, 11-file 500-LOC budget, marker scan, and
-diff checks are clean. Hosted checks and review apply to the new exact merge
-head only.
-
-
-## PR #4288 corrected-ground propagation
-
-Exact corrected #4285 parent
-`788aa547651a3685a363ea401824a5d81477bafb` is incorporated into
-`feat/4269-flight-ground-transfer` by the normal merge containing this handoff.
-PR #4288 keeps base `feat/4268-ground-contract`; neither branch was rebased,
-retargeted, rewritten, or force-pushed. The child retains its qualified
-cross-runtime terminal-state/contact transfer and inherits the corrected UTC
-parser plus canonical `swing_sim` import identity.
-
-This is ancestry propagation, not bounce, skid, roll, terrain response, total
-distance, or UI delivery. Protected CI, independent review, and normal stack
-collapse remain open.
-
-Merged-tree validation is `951` Python tests, `106` React files / `661` tests,
-and `26` focused Rust transfer/wire tests. The affected cross-version suite is
-also `110` tests on real CPython 3.10.20. The 189-module Vite production build,
-TypeScript, zero-warning ESLint, Ruff check/format across 82 files, pinned mypy
-1.13 across the six-file transfer and 13-file parent production namespaces,
-Rust workspace format plus warning-denied `tools-core` clippy, campaign-manifest
-validator plus eight contracts, documentation governance, 13-file 500-LOC
-budget, marker scan, and diff checks are clean. Hosted checks and review apply
-to the new exact merge head only.
+## 2026-08-11 PR #4342 append-only preservation repair
-
-> **Update this file with every PR and every push to main.**
-> Last updated: 2026-08-11
+Independent audit of local merge `e7fedfb18de1550eed3484ed2fc99d0baaecdca1`
+found that three older parent ancestry sections had been summarized instead of
+retained verbatim. This docs-only follow-up restores the full parent text below
+without changing production code, tests, schemas, manifest state, PR base, or
+release claims. The exact parent sections and SPEC rows are now governed by
+byte-for-byte comparison against
+`d21741e312b849a63f73cabf351a15d9de80fb94`.
## 2026-08-11 PR #4335 current-parent ancestry candidate
@@ -279,55 +144,6 @@ now records open PR #4332 at its still-published child head and open PR #4304
at its exact newly published parent head; neither record claims protected or
main-release evidence.
-## 2026-08-11 Ground-impact bounce receives current flight-transfer parent
-
-Open draft PR `#4302` retains `feat/4270-ground-impact-bounce` over
-`feat/4269-flight-ground-transfer`. Exact remote bounce child
-`cf6e72bad98e5f36f782254942e6895b8b71e670` is merged first and exact current
-transfer parent `c39297d37a17d5d8d3520ed62c5563cdcc609cab` second by an
-ordinary no-ff merge. The child-owned impact and repeated-bounce contracts,
-tests, fixture, and explicit limitations remain intact while inheriting current
-strict-ground and cross-runtime flight-transfer ancestry.
-
-Three inherited PR-delta Python files receive only their pinned Ruff 0.14.10
-layout. Analysis, persistence, and contract assertion behavior are unchanged.
-
-Local verification passes `1129` Rate/ground/flight Python tests, `25` focused
-React transfer tests, and `137` Rust tests. TypeScript, zero-warning ESLint, the
-189-module Vite build, Rust format/clippy, pinned Ruff 0.14.10, pinned MyPy
-1.13, Bandit medium/high, manifest parsing, history preservation, and diff
-checks are green.
-
-This is a local `not_released` candidate. Skid, roll, rest, total distance,
-final ground results, UI, TypeScript bounce physics, and compiled bounce
-runtimes remain outside this slice. Publication, protected exact-head CI,
-review, approval, dependency integration, and release remain open.
-
-## PR #4285 workspace timestamp propagation
-
-Exact corrected #4282 parent
-`5f77af4add23547a21cc3fabce98ae9ad4260427` is incorporated into
-`feat/4268-ground-contract` by the normal merge containing this handoff. PR
-#4285 keeps base `feat/4197-capability-observer`; neither branch was rebased,
-retargeted, rewritten, or force-pushed. The child retains its strict
-flight-to-ground contract and inherits the deterministic Python 3.10-3.12 UTC
-parser plus complete variation, scalar, wind, capability, and release ancestry.
-
-The preceding exact-head Python 3.12 CI lane loaded embedded
-`src.shared.python.swing_sim` tests and canonical `shared.python.swing_sim`
-imports as distinct package trees, producing ground/impact collection errors.
-The shared alias registry now coalesces that package root. A subprocess identity
-contract failed before the fix and now passes together with both affected
-public-API suites. The file-size job was cancelled in checkout before its
-budget step and is not a code failure.
-
-Merged-tree evidence is `915` Rate/ground/impact Python tests, all `12` shared
-alias architecture tests, `28` focused tests on CPython 3.12, `28` direct
-workspace compatibility tests on real CPython 3.10.20, and `104` React files /
-`642` tests. The production build, TypeScript, zero-warning ESLint, Ruff,
-format, pinned mypy 1.13, campaign manifest and eight contracts, docs
-governance, 500-LOC budget, marker scan, and diff checks pass.
-
## 2026-08-11 PR #4304 current-parent ancestry candidate
The clean dedicated `feat/4271-ground-skid-roll` worktree first fast-forwarded
@@ -350,6 +166,180 @@ the official changed-file 500-LOC budget, and mandatory production limits of
local merge is a PUBLISH candidate for independent review only; protected
exact-head CI, approval, normal child propagation, and publication remain open.
+
+## 2026-08-11 PR #4342 current-parent reconciliation candidate
+
+The clean `feat/4274-regional-plan-io` worktree normally merges exact
+published PR #4342 child `8e1c7ccd99a7c4886c5fb9ccc7e4d94a6d7e3833`
+with exact newly published PR #4339 parent
+`d21741e312b849a63f73cabf351a15d9de80fb94` as its second parent. PR #4342
+continues to target `feat/4274-regional-surface-ui`; neither branch is rebased,
+retargeted, rewritten, force-pushed, or published by this reconciliation.
+The merge preserves strict regional request import/export together with the
+parent's frozen engineering-number specification and bounded helper.
+
+The child widget module now delegates its canonical-precision controls to that
+shared three-parameter helper while retaining the inclusive cross-runtime safe
+number bounds and eleven-decimal presentation required by its I/O contract.
+Merged-tree qualification is 53 focused Python/PyQt/shared-ground tests and 14
+focused React tests passing. Pinned Ruff 0.14.10 check/format, MyPy 1.13 over
+all ten affected production modules, Bandit medium/high screening, TypeScript,
+zero-warning ESLint, and the 199-module production build pass. Campaign
+manifest validation and all eight manifest tests, documentation and tool
+manifest governance, changed-Python, minimum-test, exact-diff assertion,
+500-LOC, parent/child diff, and whitespace gates pass. Mandatory structural
+maxima are 396 module lines, 40 function lines, and three parameters.
+The local merge is not protected or release evidence. Independent review,
+ordinary fast-forward publication, fresh protected CI/approval, dependency
+integration, and release remain required.
+
+## 2026-08-11 PR #4339 structural helper repair candidate
+
+This parent follow-up descends exact independently reviewed reconciliation
+candidate `eedad6d23b517eb4c99d4ba9000ff6555101099f`. Independent review found
+one publication blocker: the regional PyQt number-input helper accepted six
+parameters, above the campaign's mandatory four-parameter limit. RED-first
+tests bind the helper's signature and all observable widget settings. A frozen
+`NumberInputSpec` validates finite positive step and finite ordered bounds
+before widget construction; the three-parameter helper preserves field names,
+values, units, ranges, increments, tooltips, and presentation order.
+
+Eight focused Python/PyQt tests and 25 focused React tests pass; the complete
+React suite passes all 108 files / 672 tests. Pinned Ruff check/format, MyPy,
+Bandit medium/high screening, TypeScript, zero-warning ESLint,
+documentation/manifest governance, changed-production, test-assertion,
+minimum-test, 500-LOC, and diff gates pass. Mandatory maxima are 400 module
+lines, 42 function lines, and three parameters. No schema, digest, regional
+physics, UI behavior, PR base, protected evidence, or release boundary changes.
+
+## 2026-08-11 PR #4339 current-parent ancestry candidate
+
+The clean `feat/4274-regional-surface-ui` worktree normally merged exact
+published child `cbb9c0a6bdc6a50f59f7a661139b9d53e1892980` with exact published
+#4335 parent `9e01ccc3e891cc45907293751a192624195a77a5`, while preserving
+#4339's `feat/4271-regional-wire-contract` base. Production UI, contract,
+resolver, regional physics, and ground ancestry merged without conflict; only
+SPEC, manifest, and handoffs were reconciled. Independent review, ordinary
+publication, protected exact-head CI/approval, dependency integration, and
+release remained open.
+
+## 2026-08-11 PR #4342 delta-MyPy follow-up
+
+Protected CI on exact PR #4342 head
+`cffe349ac0a8054f1d168cb36684fd00bc5f8a49` identified one redundant `bool`
+cast in the regional atomic-write adapter under the Linux delta-MyPy gate. The
+cast is removed; the typed helper's direct Boolean return is preserved. This
+changes no wire bytes, validation, file semantics, UI behavior, or physics.
+Focused persistence tests and the CI-equivalent pinned MyPy command pass
+locally; fresh protected CI/review and dependency ordering remain required.
+
+## 2026-08-11 regional request I/O protected publication
+
+Branch `feat/4274-regional-plan-io` is published normally as draft PR
+[#4342](https://github.com/D-sorganization/Tools/pull/4342), targeting exact
+PR #4339 branch `feat/4274-regional-surface-ui` at parent head
+`cbb9c0a6bdc6a50f59f7a661139b9d53e1892980`. Its reviewed implementation
+head is `d748e7a5ef3da5e6ce7737ff6829e0f14665fe97`; publication commits change
+no runtime behavior. Protected CI, independent review, issue #4274, parent
+ordering, integration, and release remain open.
+
+## 2026-08-11 bounded regional request read follow-up
+
+Independent review of local safe-number commit
+`10c394f6b1fd2927e7f3b1f96cc097cae6bfd380` found that native request import
+checked file size with `stat()` and then performed a separate unbounded text
+read. A concurrently grown or replaced file could therefore allocate beyond
+the 1 MiB wire cap before the strict parser rejected it.
+
+Native import now opens one binary handle, reads at most the wire cap plus one
+sentinel byte, rejects overflow, strictly decodes UTF-8, and only then delegates
+to the unchanged canonical v1 parser. Tests simulate content growth after the
+metadata check and reject invalid UTF-8 explicitly. The complete regional and
+atomic persistence set is 28 tests passing. This changes no schema, digest,
+physics, browser behavior, or write semantics. Static and governance evidence
+is recorded in this commit: Ruff, Ruff format, Black, focused MyPy, manifest,
+module-size, documentation-governance, and diff checks pass. The child remains
+local and unprotected.
+
+## 2026-08-11 regional request I/O safe-number follow-up
+
+Independent review of local commit `e39edf4b50b1fb9811b0032bec4758c7a08c9b74`
+found two cross-runtime representation gaps. The PyQt6 precedence spin box
+silently narrowed otherwise valid v1 integers above 1,000,000, and Python
+accepted integer-valued wire numbers above JavaScript's exact safe range.
+
+The native editor now uses an exact decimal integer entry for precedence and
+preserves every v1 value from zero through 9,007,199,254,740,991 without a
+floating-point conversion. Shared Python canonical-number and ground-record
+validation now reject magnitudes outside that same range, matching React while
+retaining all finite fractional values inside it. PyQt6 floating-point editors
+publish the same bounds. Regression coverage pins exact maximum-precedence
+open/save round-trip and matched native/browser refusal of unsafe material
+numbers. This changes no schema version, provenance algorithm, physics, or
+browser filesystem limitation. Final local evidence is 132 shared ground tests,
+21 regional editor/I/O tests, five atomic-workspace tests, 23 focused React
+tests, the whole-shell tooltip sweep, and eight manifest tests passing. Ruff,
+Ruff format, Black, focused MyPy, TypeScript, zero-warning ESLint, the 199-module
+production build, module and changed-file size budgets, documentation
+governance, and diff checks pass. The child remains local and unprotected.
+
+## 2026-08-10 PR #4339 stale-validation invalidation follow-up
+
+Rendered exact-head browser QA found that a validated one-overlay readback
+remained visible after adding a second overlay. The broad PyQt6 suite also
+found missing hover hints on the new controls. PyQt6 and React now clear both
+canonical readback and prior validation state whenever any identity, interval,
+material, or overlay-row draft value changes; PyQt6 exposes the explicit
+"Changes not validated" pending state, and every PyQt6 interactive has a
+specific engineering-context tooltip. RED-first regression tests cover the
+dynamic-row path on both surfaces. Final local evidence is 870 Python/PyQt
+tests and 672 React tests passing; Ruff, format, MyPy, TypeScript, zero-warning
+ESLint, the 198-module production build, manifest/docs/file-size governance,
+and diff checks are clean. The known polynomial-generator empty-legend warning
+is unrelated. This changes no wire schema, provenance digest, physics, or
+persistence boundary; fresh protected CI is still required before merge.
+
+> **Update this file with every PR and every push to main.**
+> Last updated: 2026-08-11
+
+## 2026-08-10 issue #4274 canonical regional request I/O local child
+
+Local branch `feat/4274-regional-plan-io` started directly from published PR
+#4339 head `a9ace5052bcd54b78f79b62d5d9ac26debedb4b1`, then fast-forwarded
+normally to corrected exact parent `cbb9c0a6bdc6a50f59f7a661139b9d53e1892980`.
+The parent's stale-validation invalidation and tooltip follow-up are preserved.
+This child has not been pushed, opened as a PR, reviewed, merged, or released.
+
+The matched Ground Surfaces editors now import and export the canonical
+`ground-regional-material-plan-request/v1` document. PyQt6 uses native Open
+and Save As dialogs plus a shared flush/fsync/atomic-replace UTF-8 writer;
+cancel is a no-op, failed reads and writes preserve the last-known-good editor
+or file, and the recent path advances only after success. React validates a
+bounded browser File before committing state and downloads exact canonical
+bytes while revoking its object URL. Browser filesystem limitations are
+explicit, and workspace persistence remains separate.
+
+Import accepts only editor producer/provider v1 evidence, the fixed target
+frame origin/downrange axis, and one to eight rows. It never relabels external
+evidence. An unchanged import round-trips the exact request and provenance;
+after any edit, validation binds a fresh draft digest. No measured calibration
+is synthesized and neither path executes physics.
+
+RED-first coverage now includes exact-byte round-trip, native cancel and
+atomic rollback, corruption, duplicate keys, oversize input, unsupported
+producer/axis qualification, stale-provenance rebinding, transactional PyQt6
+population, browser rollback, URL cleanup, and pre-allocation size rejection.
+Focused evidence is 25 Python/PyQt tests and 12 React tests passing. With
+adjacent wire and manifest coverage, 44 Python and 16 React tests pass.
+Focused MyPy, Ruff, TypeScript, zero-warning ESLint, the 199-module production
+build, release-manifest validation, and module budgets are clean.
+
+Issue #4274 remains open. Measured calibration, workspace model-input
+persistence, execution/playback, result interchange, visualization, changing
+geometry, compiled regional physics, downstream parity, protected CI/review,
+integration of this child into the protected stack, and release remain explicit
+gaps.
+
## 2026-08-10 issue #4274 matched regional surface editor local child
Local branch `feat/4274-regional-surface-ui` started from published PR #4335
@@ -521,420 +511,6 @@ fixture bytes. There is no physics, numerical, schema, or API change. SPEC
a finding-free local scan of the affected file, documentation governance, the
`370`-line source-size check, and diff gates pass; fresh protected CI/review
remain required after a normal guarded push.
-## 2026-08-11 Flight-ground transfer receives current strict-ground parent
-
-Open draft PR `#4288` retains `feat/4269-flight-ground-transfer` over
-`feat/4268-ground-contract`. Exact remote child
-`df716ac740beb9d47dced66f867dc3dde1fa5367` is merged first and exact current
-parent `584e4e53a7990053a346938c4e45538786887ec7` second by an ordinary
-no-ff merge. All transfer production/tests/fixtures and Python, TypeScript,
-Rust, PyO3, and WASM contracts remain intact. Only append-only handoff/SPEC
-records conflict, and both dated histories are retained. Focused verification
-passes 85 Python, 25 React, and 137 Rust tests; pinned Ruff 0.14.10, MyPy 1.13,
-Bandit, TypeScript, exact-delta ESLint, the production web build, Rust format,
-docs, strict manifest, diff, exact transfer-tree, and append-only preservation
-gates pass. Publication, protected exact-head CI, review, approval, and release
- remain open.
-
-## 2026-08-11 PR #4288 append-only history preservation repair
-
-This documentation-only follow-up to exact local candidate
-`1eb4188ff1a87a3d8e9a55aeca68194ca04e0bb4` restores every omitted parent
-handoff section and specification row and repairs the interleaved paragraph
-below. Production code, tests, schemas, the campaign manifest, child-first
-merge topology, and #4288's `feat/4268-ground-contract` base are unchanged.
-Publication, protected exact-head CI, approval, dependency integration, and
-release remain open.
-
-## 2026-08-11 PR #4288 current-ground-parent ancestry candidate
-
-The clean `feat/4269-flight-ground-transfer` reconciliation starts from exact
-published child `afb1bdcfc6701caaf1f7bc3497a6a37dd9698c14` and normally merges
-exact newly published #4285 parent
-`e09ab96280cab363b36bd0e7db4a3cd064dc2527` second without changing #4288's
-base. The child's bounded `flightIntegrator.ts` facade is preserved instead of
-restoring the parent's superseded inline loop, while kinetics resolves to the
-parent's split validated implementation. Seven child-owned Python files receive
-pinned Ruff 0.14.10 normalization with no AST change; the preserved TypeScript
-facade uses standard line endings. Bounce, skid, roll, terrain response, total
-distance, UI integration, protected evidence, and release remain open.
-
-> Update this append-only handoff with every implementation commit and every
-> push to `main`. Last updated: 2026-08-11.
-
-## 2026-08-11 Ground contract receives current capability carrier
-
-Open draft PR `#4285` retains branch `feat/4268-ground-contract` and base
-`feat/4197-capability-observer`. Exact remote ground-contract child
-`e09ab96280cab363b36bd0e7db4a3cd064dc2527` is merged first and exact current
-capability-observer parent `d0b827667e61f0583e1dad0b3cbbca6819624d3c`
-second by an ordinary no-ff merge. All strict flight-to-ground production,
-tests, schemas, fixtures, dependencies, and fail-closed limitations are
-preserved. Only append-only handoff/SPEC files conflict; their dated records
-from both parents remain. Publication, protected exact-head CI, review,
-approval, release, and downstream #4288 propagation remain open. Focused
-verification passes 214 Python/PyQt tests, pinned Ruff 0.14.10 across 27
-PR-delta Python files, pinned MyPy 1.13 across 20 production files, and Bandit's
-medium/high threshold. Docs, strict manifest, diff, exact ground-tree, and
-both-parent append-only preservation gates pass.
-
-## 2026-08-11 Merged capability-observer carrier receives current wind workflow
-
-PR `#4283` is merged, while its former head branch
-`feat/4197-capability-observer` remains the base of open draft PR `#4285`.
-Exact remote/local carrier child
-`b2baf6ef615b0d756a86ac4ca7eef2fc583210ee` is merged first and exact published
-#4282 parent `3faf9e9493c9ba37168d9f65ab10cafeedc2a72f` second by a normal
-no-ff merge. Since the carrier is already the first parent of #4282, the source
-merge is conflict-free: the complete capability-observer implementation and
-history remain present while the exact current wind workflow and manifest tree
-are inherited. Only handoff/SPEC carrier records differ from #4282. All 86
-focused Python/PyQt capability, wind, and manifest tests and all 86 tests in 12
-focused React capability/wind suites pass. React type-check, zero-warning lint,
-and the production build pass. Docs, manifest, and exact-parent diff gates pass;
-changed-Python static gates are not applicable to the documentation-only exact
-delta. This local audit does not authorize publication; review,
-protected CI, and
-later dependency propagation into #4285 remain open.
-
-## 2026-08-11 Wind workflow receives newly published scalar-adapter parent
-
-PR `#4282` keeps branch `feat/4199-wind-workflow` and base
-`feat/4199-wind-scalar-adapter`. Exact published child
-`b2baf6ef615b0d756a86ac4ca7eef2fc583210ee` is merged first and exact current
-parent `9321c1d2e091b8c7e5a4a83aa9ad726290e7fb5a` second. Implementation and test
-paths merge automatically: responsive PyQt6/React wind execution,
-progress/cancellation, controls, scatter, persistence/export, consolidated
-capability workflow, and strict campaign release authority remain intact while
-the parent contributes current scalar-adapter, variation, workspace,
-launch-monitor/D-plane, split-kinetics, and Qt repairs. Only append-only
-handoffs and SPEC conflict textually; both histories are preserved. All 94
-focused Python/PyQt wind, responsive-layout, navigation, playback, and manifest
-tests pass, as do all 44 tests in eight focused React wind/responsive suites.
-Docs governance and strict campaign-manifest generation/validation pass.
-Pinned Ruff checks/formats all 57 changed Python files; pinned MyPy accepts 38
-production files; pinned Bandit finds no medium/high issues in 37 scanned source
-files; the 500-LOC, changed-Python policy, test-contract/assertion, diff, React
-type-check/lint, and production-build gates pass. Review, ordinary publication,
-protected exact-head CI, unresolved threads, dependency order, and release
-remain open.
-
-## 2026-08-11 Wind workflow receives current scalar-adapter parent
-
-PR `#4282` remains on `feat/4199-wind-workflow`, based on
-`feat/4199-wind-scalar-adapter`. Exact remote child
-`29e15d6ff631f7f30afcc745be783f2e716d7dcf` normally merges exact published
-parent `a7dce5f89b483303938f518b74b4028a1c68ba81` second, preserving child-first
-history and the existing base. The responsive PyQt6/React workflow and
-consolidated capability stack inherit the parent's split kinetics facade,
-Ground/Tee parity, and 252-line public/213-line private wind-adapter repair.
-
-The only source conflict is an obsolete formatting-only edit to the pre-split
-kinetics monolith and resolves wholly to the validated parent facade. Both
-append-only documentation histories remain present. Seven surviving
-child-owned paths receive only repository-pinned Ruff formatting. The exact
-skipped-import MyPy profile also replaces one now-unused cache-return ignore
-with an explicit `KineticsSeries | None` cast; the cached object and runtime
-behavior are unchanged. Protected exact-head CI, independent review,
-unresolved-thread checks, publication, and dependency order remain release
-gates.
-
-Local evidence is 74 focused Python/PyQt wind, kinetics, and Ground/Tee tests;
-29 focused React tests; and 8 campaign-manifest tests. TypeScript, focused
-zero-warning ESLint, Ruff check/format, pinned MyPy 1.13, Bandit's medium/high
-threshold, strict wind module/signature/function budgets, manifest,
-documentation, policy, SPEC, and diff gates pass.
-
-## 2026-08-11 Ground contract receives current workflow/base ancestry
-
-Draft PR `#4285` keeps branch `feat/4268-ground-contract` and base
-`feat/4197-capability-observer`. Exact published child
-`7a38b9838d743e051a6900620c4d6e754582aa89` is merged first with exact current
-base/workflow head `b2baf6ef615b0d756a86ac4ca7eef2fc583210ee` second. The base contains
-merged #4283 head `9bbb98e16e435a0d4c74153b909f2ebfefbbce7a`; no rebase, retarget,
-force-push, parent rewrite, or publication is used.
-
-The child's strict UI-neutral `flight-to-ground/v1` schemas, canonical fixture,
-migrations, legacy-result adapter, explicit dependency, enum compatibility,
-and fail-closed validation remain authoritative. The parent contributes the
-current responsive wind/capability ancestry, Ground/Tee parity, and split
-kinetics modules. Its facade wholly resolves the sole formatting-only source
-conflict; both append-only documentation histories remain present.
-
-The ground branch's contract-checked scalar extraction repair remains intact.
-Because it makes the plotting catalog part of the effective delta, the former
-459-line registry now delegates immutable ordered rows to focused private
-scalar/series modules. The public catalog facade is 61 lines; every changed
-production module is at most 400 lines, every function at most 50 lines, and
-every signature at most four non-receiver parameters. Stable keys, display
-order, units, categories, extractor behavior, and public objects do not change.
-
-Complete local regression evidence is 1,539 Rate/shared-swing Python tests
-passed with one explicit optional Rust-wheel skip; 106 React files / 648 tests,
-TypeScript, zero-warning ESLint, and the 188-module Vite build passed; and all
-12 `swing-core` Rust tests passed. The focused ground, Ground/Tee parity,
-kinetics, wind adapter, compatibility, and manifest set passes 146 tests; 57
-additional plotting/catalog/variation/kinetics regressions pin the structural
-split. Pinned Ruff 0.14.10, MyPy 1.13, Bandit 1.7.7, manifest, documentation,
-SPEC, policy, diff, and structural gates are required again on the committed
-candidate before publication.
-
-This is an unpublished local candidate. It does not claim bounce, skid, roll,
-terrain, total distance, ground UI, Rust/WASM ground delivery, protected CI,
-approval, or release. Independent review and fresh protected checks are
-required before normal publication and later #4288 propagation.
-
-## 2026-08-10 Repaired scalar-adapter propagation into wind workflow
-
-Draft PR `#4282` remains on `feat/4199-wind-workflow`, based on
-`feat/4199-wind-scalar-adapter`. It now normally incorporates repaired parent
-head `d6fb04e07c2a625412e9208b07103acdc42c621b` after that head's quality gate
-passed. The merge had no wind-workflow production/test conflict and used no
-rebase, retarget, force-push, or history rewrite. Twenty-five focused tests and
-the documentation, size, and whitespace gates pass locally; protected CI,
-review, and later-stack propagation remain outstanding.
-
-## 2026-08-10 Exact-head manifest typing repair
-
-PR #4282 exact head `aa6eeffb0395f7ed7954f2315b1c625cada552d8`
-failed hosted quality-gate run `31395741841` only at pinned-mypy
-`scripts/rate_campaign_manifest.py:335:5 [no-any-return]`. The CI profile skips
-import analysis, so the Pydantic validator result becomes `Any`; an explicit
-local `CampaignManifest` annotation now retains the validated return contract
-without changing parsing, validation, or error behavior. Ruff and format had
-already passed on the failed head. Publish this repair normally, then propagate
-its new exact head into #4285; do not retry the obsolete run.
-
-## 2026-08-10 Wind workflow receives exact scalar-adapter parent
-
-PR `#4282` keeps branch `feat/4199-wind-workflow`, base
-`feat/4199-wind-scalar-adapter`, and original child first parent
-`5f77af4add23547a21cc3fabce98ae9ad4260427`. Exact parent
-`4a793c4c3f19aad43a3c215800b266be487ace49` merges normally second. The
-responsive PyQt6/React wind strategy workflow, consolidated capability stack,
-and campaign release authority remain additive with the parent's complete
-variation, workspace, compatibility, and strict scalar-adapter history.
-
-The parent's extracted navigation-state tuple is the single authority and now
-includes the child-owned `capability_optimization` ID. This preserves safe
-legacy visibility migration and prevents a persisted pre-capability workspace
-from hiding the new tab. Runtime-only UI and capability invariants now raise
-explicit errors under optimized Python, and the safe fixed-argument builder
-subprocess is annotated for Bandit. The skipped-import manifest return repair
-is recorded above. SPEC 1.14.15 is the current exact-head repair entry.
-Verification passes 73 focused Python tests, the complete 1,657-test
-Rate/shared-swing/golf-club matrix with two explicit optional build123d skips,
-all 643 React tests across 105 files plus type-check/lint/build, 12 Rust tests,
-31 real-CPython-3.10 compatibility tests, and 43 post-review invariant/GUI/
-manifest tests. Ruff/format, pinned MyPy 1.13 across 37 changed production
-files, Bandit, exact-parent size, manifest, docs, minimum-test, assertions,
-CI-policy secrets, compilation, and diff gates pass. Independent re-review
-found no actionable findings after 94 Python workflow/navigation tests, 20
-manifest/GUI tests, 61 React workflow tests, and independent static checks.
-Protected CI/review and dependency-ordered propagation remain release gates.
-
-## Current continuation
-
-The active local continuation is integrated directly on the existing PR #4282
-carrier `feat/4199-wind-workflow`, starting from original published head
-`5f77af4add23547a21cc3fabce98ae9ad4260427` and normally incorporating exact
-published #4281 parent `4a793c4c3f19aad43a3c215800b266be487ace49`.
-The base remains `feat/4199-wind-scalar-adapter`; no branch was rebased,
-retargeted, force-pushed, or published by this continuation. It adds strict
-cross-runtime capability parsing, reliable signed decimal entry, complete
-ranked diagnostics and result exports, quantitative React scatter annotations,
-package-safe static-web release entrypoints, and the strict
-`rate-of-closure-campaign/v1` release authority. It also carries the corrected
-parent's Python 3.10 compatibility, variation-export, scalar-ensemble, and
-wind-adapter history. Normal publication does not establish a protected
-release; CI, review, and downstream evidence remain required.
-
-The direct web launcher dynamically loads the root bootstrap module without a
-launcher-local `sys.path` mutation; its subprocess delegation test and the
-changed-production-Python policy guard cover this release entrypoint.
-
-Use these authorities together:
-
-- `docs/release/rate_of_closure_campaign.v1.json` — machine state;
-- `scripts/rate_campaign_manifest.py` — validation and generated JSON Schema;
-- `docs/release/RATE_OF_CLOSURE_CAMPAIGN_MANIFEST.md` — update procedure;
-- `docs/development/RATE_OF_CLOSURE_CAMPAIGN_HANDOFF.md` — detailed history;
-- `docs/specs/*.md` — scientific and interoperability contracts.
-
-The manifest is intentionally normalized: programs reference shared carrier
-and test-evidence records. It fails on missing primary issues, undeclared
-references, duplicate IDs, malformed SHAs, absent repository evidence,
-placeholders, and contradictory release claims.
-
-## Carrier state
-
-The capability stack was collapsed top-down on 2026-08-09:
-
-1. #4294 Shot Optimizer UI merged into `feat/4197-capability-flight-evaluator`;
-2. #4289 evaluator merged into `feat/4197-capability-observer`;
-3. #4283 observer merged into `feat/4199-wind-workflow`.
-
-These were feature-parent merges, not protected releases. Current carrier
-#4282 descends from #4281 → #4280 → #4279 → #4203 → #4202 → wedge and
-variation parents. Exact published #4281 parent
-`4a793c4c3f19aad43a3c215800b266be487ace49` is incorporated locally. Preserve
-that dependency order and use normal merges only.
-
-Outer platform PR #4119 targets `main` and still needs reconciliation. PR #4133
-impact-interval dynamics merged into a historical feature parent after that
-parent had already propagated, so its source and tests must be explicitly
-reconciled before #4130 can close.
-
-## Implemented on the feature stack
-
-- PyQt6 and React variation workspaces: selectable input/contact/impact/shot
- scatter, matrix, landing dispersion, every-trial 3D swing arcs, quiet zones,
- linked selection, bounded raw rows, and lossless exports.
-- Matched toolstrip/workspace controls, module visibility, independent plots,
- legend placement, zoom/autofit, replay, loop, and granular playback rate.
-- Launch-monitor convention, D-plane, spatial target, inverse flight, wind,
- interactive flight playback, and capability-optimization contracts/workflows.
-- Wedge kinematics, clearance, turf proxy, impact visualization, and
- forgiveness-analysis slices.
-
-## Current limitations
-
-- No complete campaign program has a qualified `main` release SHA.
-- Capability v1 is still-air carry to first ground crossing; it excludes wind,
- bounce, roll, and total distance in that evaluator.
-- Ground contracts and flight transfer are open carriers; qualified bounce,
- skid, roll, profiles, total-distance optimization, UI, and Rust/WASM parity
- remain.
-- UpstreamDrift React has no native Rate route, and the Tools source pin and
- resolver behavior are not a qualified immutable parity boundary.
-- Camera tracking/snap views (#4284), complete persistence adapters, high-DPI,
- keyboard, reduced-motion, and visual-regression matrices remain open.
-- Local/rendered evidence is not protected CI or installed-package evidence.
-
-## Most recent evidence
-
-- Corrected-parent propagation: 62 focused wind/scalar/variation and
- compatibility tests pass on Python 3.11 and real CPython 3.10.20; 8 React
- files / 35 tests, TypeScript, and focused zero-warning ESLint pass. The real
- 3.10 run found and now guards #4282's child-owned capability-observation
- `StrEnum` boundary. Ruff check/format passes 15 focused files, pinned mypy
- 1.13 passes 10 production modules, and nine campaign manifest/parity
- contracts pass.
-- Composed local continuation: 828 Rate Python/PyQt tests and 104 React files /
- 642 tests passed; TypeScript, zero-warning ESLint, and the 188-module Vite
- production build passed. The manifest, schema JSON, Ruff, targeted mypy, and
- nine manifest/parity contracts pass on implementation head `2c1a77baa`.
- Hosted CI has not run on this composition.
-- Hosted quality-gate run `31340032608` subsequently found mypy 1.13
- `no-any-return` findings at the Pydantic loader and Qt elapsed-timer adapter
- under `--follow-imports=skip`; both boundaries now narrow their return values
- explicitly. The exact Python 3.12/mypy 1.13 delta is clean across 54 files;
- Ruff, 62 focused regression tests, and eight campaign-manifest tests also
- pass locally.
-- Consolidated capability head `c1827bbdc`: 1,426 Python Rate/shared-swing
- tests and 624 React tests passed locally.
-- Variation continuation `d71b0ea01`: 890 Python/PyQt/shared-swing tests and
- 545 React tests passed locally, with one optional Rust skip.
-- Toolstrip head `c36ca36e9`: the same 890/545 local suite totals passed.
-- Hosted #4282 head `3186a265b1`: `swing_core` built, but cached plugin loading
- failed before parity collection; this is failed evidence, not a model pass.
-- CI-isolation head `18fe89201`: focused workflow regression passes locally;
- the hosted non-skipped parity run is still required.
-
-## Validation
-
-```powershell
-python scripts/rate_campaign_manifest.py
-python -m pytest tests/rate_of_closure/test_campaign_release_manifest.py -q
-$env:QT_QPA_PLATFORM='offscreen'
-$env:PYTHONPATH=(Resolve-Path 'src').Path
-python -m pytest tests/rate_of_closure src/shared/python/swing_sim -q
-cd src/rate_of_closure/web
-npm test -- --run
-npm run type-check
-npm run lint
-npm run build
-```
-
-## 2026-08-11 Wind workflow receives current scalar-adapter parent
-
-PR `#4282` remains on `feat/4199-wind-workflow`, based on
-`feat/4199-wind-scalar-adapter`. Exact remote child
-`29e15d6ff631f7f30afcc745be783f2e716d7dcf` normally merges exact published
-parent `a7dce5f89b483303938f518b74b4028a1c68ba81` second, preserving child-first
-history and the existing base. The responsive PyQt6/React workflow and
-consolidated capability stack inherit the parent's split kinetics facade,
-Ground/Tee parity, and 252-line public/213-line private wind-adapter repair.
-
-The only source conflict is an obsolete formatting-only edit to the pre-split
-kinetics monolith and resolves wholly to the validated parent facade. Both
-append-only documentation histories remain present. Seven surviving
-child-owned paths receive only repository-pinned Ruff formatting. The exact
-skipped-import MyPy profile also replaces one now-unused cache-return ignore
-with an explicit `KineticsSeries | None` cast; the cached object and runtime
-behavior are unchanged. Protected exact-head CI, independent review,
-unresolved-thread checks, publication, and dependency order remain release
-gates.
-
-Local evidence is 74 focused Python/PyQt wind, kinetics, and Ground/Tee tests;
-29 focused React tests; and 8 campaign-manifest tests. TypeScript, focused
-zero-warning ESLint, Ruff check/format, pinned MyPy 1.13, Bandit's medium/high
-threshold, strict wind module/signature/function budgets, manifest,
-documentation, policy, SPEC, and diff gates pass.
-
-## 2026-08-10 Final repaired workflow ancestry in strict ground contract
-
-Draft PR `#4285` remains on `feat/4268-ground-contract`, based on
-`feat/4197-capability-observer`. Its original head
-`e5bcbd1096d3be1f621a805c9d9f3fd321e375a5` normally incorporates exact
-quality-green #4282 head `1e82f15026786ea0b08f78f4c001590ddce9ff39`
-second. Ground-contract source and tests had no conflict. Protected CI and
-review must pass before the new exact head propagates normally into #4288.
-
-## 2026-08-10 Final repaired strict-contract ancestry in flight transfer
-
-Draft PR `#4288` remains on `feat/4269-flight-ground-transfer`, based on
-`feat/4268-ground-contract`. Its original head
-`108a841b1378c992defd3c7b7ee263d41a6c8b24` normally incorporates exact
-quality-green #4285 head `a93edb4bfd6a8dc9334122cd2ae660983d5bf424`
-second. Transfer source and tests had no conflict. Fresh protected CI and review
-must pass before any release claim.
-
-## PR #4288 exact repaired-ground propagation
-
-Original child `247215422a6d4b677552955b4923bc609a553259` normally incorporates
-exact repaired #4285 parent `e5bcbd1096d3be1f621a805c9d9f3fd321e375a5`
-second in the merge on `feat/4269-flight-ground-transfer`. PR #4288
-keeps base `feat/4268-ground-contract`; neither branch was rebased, retargeted,
-rewritten, or force-pushed. The child retains its qualified cross-runtime
-terminal-state/contact transfer and inherits the corrected UTC parser,
-canonical `swing_sim` import identity, hosted-mypy manifest repair, and the
-complete variation, wind, capability, and campaign ancestry.
-
-This is ancestry propagation, not bounce, skid, roll, terrain response, total
-distance, or UI delivery. Protected CI, independent review, and normal stack
-collapse remain open.
-
-Exact composed-tree verification is 1,080 Python tests passed with six explicit
-optional installed-`tools_core` wheel skips, 107 React files / 662 tests,
-26 direct Rust transfer/wire tests, TypeScript, zero-warning ESLint, and the
-189-module production build. Ruff check/format passes all 28 changed Python
-files; pinned mypy 1.13 passes all 21 changed production files. Campaign
-manifest, documentation governance, and diff checks pass. The missing local
-wheel remains an explicit installed-package release boundary and is not
-misreported as accelerated parity evidence.
-
-## 2026-08-10 Exact repaired #4282 propagation into PR #4285
-
-Original child `788aa547651a3685a363ea401824a5d81477bafb`
-normally incorporates exact repaired #4282 parent
-`686016196a2f895058b8a566dff103a0fd32cd10` second on
-`feat/4268-ground-contract`. PR #4285 keeps base
-`feat/4197-capability-observer`; neither branch was rebased, retargeted,
-rewritten, or force-pushed. The parent contains merged capability PR #4283,
-its exact observer head, and the exact-hosted-mypy manifest repair. The child
-retains its strict flight-to-ground contract while acquiring the latest
-deterministic variation, workspace, wind, capability, and release ancestry.
## 2026-08-09 PR #4304 corrected implementation evidence
@@ -1027,45 +603,6 @@ regions, changing normals, deformation/grass response, torsional spin damping,
roll-to-skid, PyQt6/React UI, compiled runtimes, UpstreamDrift consumers,
protected review, parent integration, and main release remain open.
-## 2026-08-10 Exact repaired #4282 propagation into PR #4285 (continued)
-
-The inherited ground descendant passes 1,703 Python tests with two optional `build123d`
-skips, 643 React tests across 105 files plus type-check/lint/build, 12 Rust
-tests, and 77 real-CPython-3.10 ground and compatibility tests. Ruff/format pass
-78 changed Python files; pinned mypy and Bandit pass 52 changed production
-files. Manifest, docs, minimum-test, assertions, 500-LOC, changed-file secrets,
-Python 3.10 compilation, and diff checks are clean.
-
-The repaired parent explicitly types the Pydantic manifest return. The composed
-tree also normalizes contract-checked scalar plot values with `float`, replaces
-the command-state `assert` with a runtime invariant error, and documents the
-alias finder's intentional optional-probe `B112` security boundary. Protected
-current-head CI and required review remain release gates. The exact repaired
-ground head is now incorporated into #4288; normal propagation of the reviewed
-#4288 head into #4298 is the next ancestry gate.
-
-## 2026-08-09 Ground parent reconciled with corrected wind carrier
-
-Draft PR #4285 keeps base `feat/4197-capability-observer` and normally
-incorporates exact corrected wind carrier
-`bb101cedd555d07d493aae998b46050c68660cdd`. No branch was rebased,
-retargeted, force-pushed, or published. The strict ground contract remains
-UI-neutral and fail closed; the merge adds no bounce, skid, roll, terrain
-profile, total distance, or presentation claim.
-
-This branch is now the carrier-reconciled ground parent. PR #4288 must merge
-the resulting exact #4285 head normally before its transfer logic is retested
-or published. That descendant merge will carry both the ground contract and
-the explicit observer-to-wind ancestry reconciliation without changing either
-PR base.
-
-Focused evidence is 89 ground/compatibility/wind tests on Python 3.11 and 89
-on real CPython 3.10.20. Ruff check/format passes 34 focused files; pinned mypy
-1.13 passes 23 production modules; the inherited campaign manifest validates
-and its nine manifest/parity tests pass. Ground production modules remain
-within the 400-line/50-line structural budgets and contain no placeholder
-markers.
-
## 2026-08-09 PR #4302 pinned-MyPy current-head correction
Hosted quality-gate run `31350134551` exposed four deterministic MyPy 1.13
@@ -1879,1190 +1416,3 @@ Publish this as a normal follow-up commit on
`feat/4270-ground-impact-bounce`, with the three handoffs in the same commit.
Keep #4270 and #4267 open; do not bypass protected CI or propagate into child
branches until the parent push is verified.
-## Inherited current-parent handoff history
-
- Python/TypeScript SHA-256 parity digests as high-entropy strings. These are
- expected deterministic test outputs, not secrets. Use only exact inline
- `pragma: allowlist secret` annotations on the four digest constants; preserve
- the repository baseline and scanner scope. Commit the annotations and this
- handoff together on the parent capability-observer branch, then re-run the
- protected stack without force-pushing or bypassing the gate. Parent commit
- `49612946138b1021f80c9f8d2a4d06f1610825db` is now propagated into this child
- by a normal merge commit.
-## Inherited #4281 handoff history
-
-## 2026-08-11 Wind scalar adapter receives current variation parent
-
-PR `#4281` keeps branch `feat/4199-wind-scalar-adapter` and base
-`feat/4144-variation-export-continuation`. Exact published child
-`a7dce5f89b483303938f518b74b4028a1c68ba81` is merged first and exact current
-parent `e6c7460a01082631565fb9ed48aa32538bd7772c` second. Implementation and test
-paths merge automatically: Python/TypeScript scalar-ensemble provenance,
-availability, deterministic-scenario, wind-strategy adapter, and strict
-module-budget behavior remain intact while the parent contributes current
-variation visualization/export, workspace, launch-monitor/D-plane ancestry,
-split kinetics, and behavior-preserving Qt return narrowing. Only append-only
-handoffs and SPEC conflict textually; both histories are preserved. All 77
-focused wind/variation Python tests and all 20 tests in the five focused React
-wind/variation suites pass before the merge commit. Pinned Ruff checks/formats
-all five changed Python files; pinned MyPy and Bandit accept all three production
-files; both 500- and strict 400-LOC, docs, changed-Python policy,
-test-contract/assertion, diff, React type-check/lint, and production-build gates
-pass. The later campaign-manifest artifact/checker/test exist on neither side of
-this pre-manifest stack and are not applicable. Review, ordinary publication,
-protected exact-head CI, unresolved threads, dependency order, and release
-remain open.
-
-## 2026-08-11 Wind scalar-adapter module-budget repair
-
-The 403-line `variation/wind_strategy_plot_adapter.py` exceeded the mandatory
-400-line ceiling. Request/analysis validation now lives in the private
-`variation/_wind_strategy_plot_validation.py` collaborator, leaving a 252-line
-public adapter and a 213-line validator. A frozen, slotted scenario-expectation
-object keeps the private scenario validator at two cohesive parameters; every
-production function is at or below four parameters and 50 lines. The public
-imports, dataset schema,
-variable/stage/category/cohort order, composite row identities, row values,
-typed availability, attributes, validation messages, and no-flight-rerun
-boundary are unchanged.
-
-The existing 14-test Python adapter suite and 16 focused React wind tests cover
-the behavior-preserving extraction; Ruff/format, pinned MyPy 1.13, Bandit, and
-the explicit strict line budget pass locally. Protected exact-head CI,
-independent review, unresolved-thread checks, ordinary publication, and stack
-order remain release gates.
-
-## 2026-08-11 Wind scalar adapter receives reviewed variation parent
-
-PR `#4281` stays on `feat/4199-wind-scalar-adapter`, based on
-`feat/4144-variation-export-continuation`. Exact remote child
-`247046d55afcad3e6cd4f8029f854856c427f59c` normally merges exact reviewed
-parent `3337945699966b63cb5cd8e52d7c3b194315e911` in child-first order,
-preserving both histories and every commit. Python/TypeScript scalar-ensemble
-provenance, typed availability, deterministic-scenario rules, and wind-strategy
-plot-adapter behavior remain unchanged. The parent supplies selected-scatter
-export, linked variation views, the kinetics split, Ground/Tee parity,
-workspace/toolstrip behavior, and protected Ruff normalization. The only
-feature-code conflict referenced obsolete monolithic kinetics and is resolved
-to the validated parent `pendulum.sample(...)` facade. This local merge still
-requires independent review, fresh exact-head protected CI, unresolved-thread
-checks, dependency order, and ordinary publication.
-## 2026-08-11 Variation export receives current workspace parent
-
-PR `#4280` keeps branch `feat/4144-variation-export-continuation` and base
-`feat/4218-toolstrip-workspace`. Exact published child
-`3337945699966b63cb5cd8e52d7c3b194315e911` is merged first and exact current
-parent `efbca84095b617b4018732f7802c2da3f0525387` second. Implementation and test
-paths merge automatically: selected-scatter CSV parity, typed unavailable
-outcomes, bounded accessible tables, linked selection, and all-trial arc
-analysis remain intact while the parent contributes current workspace,
-launch-monitor/D-plane ancestry, split kinetics, and behavior-preserving Qt
-return narrowing. Only append-only handoffs and SPEC conflict textually; both
-histories are preserved. All 56 focused Python variation tests and all 10 tests
-in the three focused React variation suites pass before the merge commit.
-Pinned Ruff checks/formats all five changed Python files; pinned MyPy and Bandit
-accept all four production files; docs, 500-LOC, changed-Python policy,
-test-contract/assertion, diff, React type-check/lint, and production-build gates
-pass. The later campaign-manifest artifact/checker/test exist on neither side of
-this pre-manifest stack and are not applicable. Review, ordinary publication,
-protected exact-head CI, unresolved threads, dependency order, and release
-remain open.
-## 2026-08-11 Variation export receives reviewed workspace parent
-
-PR `#4280` stays on `feat/4144-variation-export-continuation`, based on
-`feat/4218-toolstrip-workspace`. Exact remote child
-`668ba96746f79f7a12e8092161bd610054197f58` normally merges exact reviewed
-parent `ccd0e026c580c93038fdf5c59d5d452a85ba27a0` in child-first order,
-preserving both histories and every commit. Selected-scatter CSV parity, typed
-unavailable outcomes, bounded accessible tables, linked selection, and
-all-trial arc analysis remain unchanged. The parent supplies its validated
-kinetics split, Ground/Tee parity contracts, protected Ruff normalization, and
-workspace/toolstrip implementation. The only feature-code conflict referenced
-obsolete monolithic kinetics source and is resolved to the current
-`pendulum.sample(...)` façade. Seven duplicate child automation edits do not
-match protected Ruff 0.14.10 output and are normalized to the exact reviewed
-parent blobs while their commit remains in history. This local reconciliation
-still requires independent review, exact-head protected CI, unresolved-thread
-checks, dependency order, and ordinary publication.
-## 2026-08-11 Workspace child receives current #4203 parent
-
-PR `#4279` keeps branch `feat/4218-toolstrip-workspace` and base
-`feat/4181-launch-monitor-registry`. Exact published child
-`ccd0e026c580c93038fdf5c59d5d452a85ba27a0` is merged first and exact current
-parent `7abce9ad767fe8311da66a1e5998b892ea3ca9de` second. Implementation and
-test paths merge automatically: the child workspace/toolstrip, visibility,
-navigation, playback, and independent-plot behavior remain intact while the
-parent contributes current launch-monitor/D-plane ancestry, split kinetics,
-and behavior-preserving Qt return narrowing. Only append-only handoffs and
-SPEC conflict textually; both histories are preserved. All 142 exact
-PR-delta Python tests and all 32 tests in the eight changed React suites pass
-before the merge commit. Pinned Ruff checks/formats all 27 changed Python
-files; pinned MyPy and Bandit accept all 18 production files; docs, 500-LOC,
-changed-Python policy, test-contract/assertion, diff, React type-check/lint, and
-production-build gates pass. The later campaign-manifest artifact/checker/test
-exist on neither side of this pre-manifest stack and are not applicable.
-Review, ordinary publication, protected exact-head CI, unresolved threads,
-dependency order,
-and release remain open.
-## 2026-08-11 Remote workspace history reconciled locally
-
-PR `#4279` retains branch `feat/4218-toolstrip-workspace` and base
-`feat/4181-launch-monitor-registry`. Exact local head
-`0b22c401a26c31441a599d8d9b39de123706e7ea` ordinarily merges divergent
-remote head `61fe2d556a5413e525d958612ccfd57e65b8d5a2`, preserving every commit in
-both histories. The remote automation commit is formatting-only: 15 of 23
-paths were already identical through the parent, while its seven unique edits
-are normalized back to protected Ruff 0.14.10 output. Its one content conflict
-referenced the obsolete pre-split kinetics implementation. The reconciled tree
-keeps the current `pendulum.sample(...)` façade path and therefore preserves
-the kinetics split, physics, frames, units, imports, schemas, and UI behavior. Workspace/toolstrip,
-visibility, navigation, playback, and independent plot behavior are unchanged.
-Publication remains blocked on independent review, fresh exact-head protected
-CI, unresolved-thread checks, and dependency order.
-
-## 2026-08-11 Workspace child receives hosted MyPy repair
-
-PR `#4279` retains branch `feat/4218-toolstrip-workspace` and base
-`feat/4181-launch-monitor-registry`. Exact child
-`7806a16f58e1c6999d32f0127a187fbb21f839a1` normally merges exact published
-parent `3796b49e40b677fbac4e05739f8be49f905df2cb`. No feature-code conflict
-exists: the inherited production delta is four static `numpy.ndarray` casts,
-while workspace/toolstrip behavior and runtime arrays, physics, frames, units,
-imports, and UI behavior remain unchanged. This local merge does not satisfy
-fresh protected CI, required review, unresolved-thread, dependency, or release
-gates.
-
-## 2026-08-11 workspace child receives latest repaired parent
-
-PR `#4279` retains branch `feat/4218-toolstrip-workspace` and base
-`feat/4181-launch-monitor-registry`. A normal merge incorporates exact parent
-`0216a547aa79727091a2939b96e779e8ddbd7304` into exact child
-`61b7f48b5aeb7d57246b4963da3df086e79cbe15`. There are no feature-code
-conflicts: workspace/toolstrip, visibility, navigation, playback, and plot
-behavior remain unchanged while the parent kinetics façade/dynamics/series
-split and pinned formatting are inherited. This local merge does not satisfy
-fresh protected CI, required review, unresolved-thread, dependency, or release
-gates.
-
-## 2026-08-11 Append-only SPEC preservation repair
-
-Independent review found that the local #4203 reconciliation omitted four
-exact D-plane parent SPEC rows dated 2026-08-10 (versions 1.13.11, 1.13.9,
-1.13.7, and 1.13.6). They are restored verbatim in a documentation-only
-follow-up. Production behavior, tests, ordered parents, base, and local quality
-evidence are unchanged; re-review, normal publication, and protected CI remain
-open.
-
-## 2026-08-11 Current D-plane parent reconciliation
-
-PR #4203's published child `217e36dc93d30f79826847f958fbcd10805e58ed`
-is being normally merged with exact current D-plane base
-`f3363aa88868f6a5c7e9ccfc682a9eca014e86c1`. The base and source branch stay
-unchanged. The only conflict is the parent's formatting of an older monolithic
-kinetics expression: the split facade keeps its typed pendulum accessor and
-inherits the parent's geometry explanation. No launch-monitor, D-plane, or
-kinetics behavior is intentionally changed. Four Qt-stub `Any` returns exposed
-by the exact MyPy 1.13 delta are also narrowed to their declared `bool`/`str`
-contracts without changing values. Focused/full validation, independent
-review, normal publication, and protected CI remain open.
-
-## 2026-08-11 Exact-head format completion
-
-Protected CI on #4203 head `7d69a545ae555679f0318940e67c1786626d6794`
-failed only Ruff formatting. The pinned 0.14.10 reproduction found eleven
-noncompliant changed Python files: four inherited files plus seven altered by
-the automated pre-commit repair. The pending repair intentionally changes no
-launch-monitor, kinetics, simulation, or UI behavior and requires independent
-review plus fresh protected CI before integration.
-
-## 2026-08-11 Hosted MyPy NumPy-return repair
-
-CI Standard run `31477542889`, job `93734652129`, found four
-`no-any-return` errors after the kinetics façade extraction at exact PR #4203
-head `0216a547aa79727091a2939b96e779e8ddbd7304`. The NumPy stubs widen
-`linalg.norm`, `concatenate`, and matrix projection results to `Any` even
-though the runtime operations return arrays. The private series/dynamics
-modules and public façade now use explicit `cast(np.ndarray, ...)` boundaries.
-These casts are static only: array identity, values, dtype, shape, physics,
-frames, units, imports, and UI behavior are unchanged. Verification must cover
-the complete PR changed-source MyPy set and both focused and full Rate tests.
-Current local evidence is 102 changed-source MyPy files, 28 focused tests, and
-all 701 Rate tests passing; complete-delta Ruff/format and Bandit are also
-green.
-
-## 2026-08-11 Kinetics façade extraction
-
-The strict current-head delta reproduces a protected size failure that the
-PR-base comparison hides: `kinetics.py` is changed versus `HEAD~1` and is 646
-LOC, above the ungrandfathered 500-LOC maximum. The public module is now a
-222-LOC run adapter/facade; its pure double-pendulum dynamics are in the
-205-LOC `_kinetics_dynamics.py`, and the immutable `KineticsSeries`/DbC
-contract is in the 131-LOC `_kinetics_series.py`. Existing public imports and
-the `_reaction_forces` seam are the same implementation objects. A RED-first
-identity test plus the existing physics, energy, force, parity-fixture,
-presentation, and PyQt tests protect behavior. No physics, frame, SI-unit,
-schema, UI, or stack-order change is intended; the commit remains local only.
-Focused kinetics/presentation/PyQt verification is 28 passing tests; the
-complete Rate-of-Closure Python regression suite is 701 passing tests.
-
-## 2026-08-11 #4203 pinned-Ruff formatting repair
-
-No material handoff change: current-head CI Standard run `31468208320`, job
-`93705508050`, identified eight files that differ from repository-pinned Ruff
-0.14.10 output. This commit changes formatting only; Rate physics, behavior,
-frames, persistence schemas, PyQt/React contracts, stack bases, and dependency
-order remain unchanged. Fresh protected CI and review are still required.
-
-## 2026-08-10 Ground/Tee parity child receives repaired parent
-
-Ready PR `#4325` keeps branch `feat/4143-tee-parity-fixture` and base
-`feat/4181-launch-monitor-registry`. It normally merges exact repaired parent
-head `12dd76a8dbcc106c4683f2f2e53076f8dc6f1b76` without any production/test
-code conflict or history rewrite. Shared parity and rendered-evidence
-contracts remain intact; fresh protected CI, review, dependency order, and
-#4143 release remain open.
-
-## 2026-08-10 #4143 Python/React Golden Ball-Setup Parity
-
-The isolated `feat/4143-tee-parity-fixture` child begins at exact draft PR
-#4203 head `31cbc007d4c85b5479b7cd0fb0969124eab2af67`. One versioned JSON fixture now
-drives both Python and React ball-support tests with explicit SI units and the
-ground-plane-to-ball-bottom height reference. The shared cases cover Driver
-and non-Driver defaults, user overrides, Ground zero effective height,
-derived ball-center geometry and serialization, negative/NaN/infinite height
-rejection, and backward-compatible migration of a legacy run without
-`ball_setup`.
-
-Evidence is 18 passing Python tee/parity tests and 24 passing React
-tee/persistence/parity tests, plus green TypeScript, ESLint, Vite production
-build, Ruff check, and Ruff format. Production model and UI code are unchanged.
-Recorded visual evidence now adds 1600 x 1200 Playwright Driver/Tee and
-rerun-Ground captures plus 1400 x 900 hidden-window PyQt captures. The browser
-run asserts control state, diagram geometry, and zero console/page errors; the
-desktop run asserts canonical center/artist state, nonblank output, and
-different Ground/Tee digests without pixel absolutes. The exact artifacts and
-versioned manifests are in
-`C:\Users\diete\AppData\Local\Temp\rate-4143-visual-evidence-8050eeba`.
-Do not close #4143: protected current-head CI/review and release to `main`
-remain. This exact parent predates the strict campaign manifest on a divergent
-branch, so no downstream manifest was copied into this bounded child.
-
-## 2026-08-10 Wind scalar child receives second repaired parent
-
-PR `#4281` retains branch `feat/4199-wind-scalar-adapter` and base
-`feat/4144-variation-export-continuation`. It normally merges exact repaired
-parent `b90e5021a59e2081415b51ef29fbed06377bc201` without scalar-adapter code
-conflict or history rewrite. Fresh child CI, review, and dependency order
-remain required.
-Post-reconciliation evidence is 25 focused D-plane/impact tests plus docs,
-changed-file-size, and whitespace gates.
-
-## 2026-08-10 Variation export child receives exact workspace parent
-
-PR `#4280` retains branch `feat/4144-variation-export-continuation`, base
-`feat/4218-toolstrip-workspace`, and original child first parent
-`f90836e342efc8be624739802375af2876d11e5f`. Exact parent
-`6717e9e09d507dbc24bedb36177f1cdf0b4fd90b` merges normally as the second
-parent. All variation visualization/export source merged without conflict:
-selected scatter CSV, typed unavailable rows, accessible bounded raw tables,
-linked trials, focused PyQt widgets, and React parity remain additive with the
-parent workspace/toolstrip/playback/plot/navigation repairs. SPEC 1.14.12 is
-the unique combined child entry. Staged review exposed a stale linked-trial
-selection when a smaller rerun replaced the active result. Corrected PyQt
-views clear result-local selection before repopulating and validate all public
-setter indices; React clears on result identity change and shares only bounded
-selections with linked views. Thirty-seven focused variation tests and the
-complete Rate/shared-swing/golf-club matrix pass 1,528 tests with two explicit
-optional build123d skips; all 546 React tests across 90 files pass;
-TypeScript, ESLint, and production build are green. Exact-parent
-Ruff/Ruff-format/Black, pinned MyPy 1.13 across four Python production modules,
-Bandit, file-size, docs, minimum-test, assertion, detect-secrets, diff, real
-CPython 3.10.20 compilation, and 30 compatibility regressions pass. There is
-no Rust delta from the exact parent. Independent staged re-review found no
-actionable findings, including the first replacement-render React boundary.
-Protected CI/review remain release gates after an ordinary guarded push.
-
-## 2026-08-10 Variation child receives second repaired workspace parent
-
-PR `#4280` retains branch `feat/4144-variation-export-continuation` and base
-`feat/4218-toolstrip-workspace`. It normally merges exact repaired parent head
-`61b7f48b5aeb7d57246b4963da3df086e79cbe15` without feature-code conflict or
-history rewrite. Variation/export behavior remains unchanged; fresh child CI,
-review, and dependency order remain required.
-Post-reconciliation evidence is 25 focused D-plane/impact tests plus docs,
-changed-file-size, and whitespace gates.
-
-## 2026-08-10 Wind scalar child receives exact variation parent
-
-PR `#4281` keeps branch `feat/4199-wind-scalar-adapter`, base
-`feat/4144-variation-export-continuation`, and original child first parent
-`cf52529b1e68479321bb93b1be3d59c77f782008`. Exact parent
-`8bcc49fc4e16e5e43be0b7f0f03c3017d5b79d0c` merges normally second. The
-child's scalar-ensemble wire contract, provenance-preserving wind rows,
-availability accounting, and plot adapter remain additive with the parent's
-variation visualization/export and result-local selection repairs. Python and
-TypeScript reject wind scenarios unless their per-trial provenance is exact,
-shear/turbulence are zero, seed is zero, and gusts are empty. SPEC 1.14.13 is
-the unique combined child entry. Twenty-seven focused Python tests, the
-1,549-test complete Rate/shared-swing/golf-club matrix with two explicit
-optional build123d skips, and all 556 React tests across 92 files pass.
-TypeScript, ESLint, production build, Ruff/format, pinned MyPy, Bandit, size,
-docs, minimum-test, assertions, detect-secrets, diff, and CPython 3.10 compile
-gates pass. Independent re-review found no actionable findings after checking
-the exact provenance derivation and all five deterministic-scenario
-regressions; protected CI/review remain release gates.
-
-## 2026-08-10 Variation child timestamp propagation
-
-The #4280 continuation now carries exact parent
-`05383d333b6fd87eaf5e37305476f50b505c2c2e` through a normal merge while
-preserving its original base and complete variation export/accessibility
-implementation. The inherited workspace parser now has one strict UTC grammar
-and consistent zero- through six-digit fractional-second behavior across
-Python 3.10-3.12. The child variation behavior is unchanged.
-
-SPEC 1.14.10 records the parent compatibility repair and 1.14.11 records the
-child variation delta. Keep this handoff, the root and campaign handoffs, and
-the reconciled SPEC in the merge commit. The combined evidence is `778 passed`
-for the Rate suite, `27 passed` on real CPython 3.10.20, and `1 file / 8 tests`
-for focused React variation, with TypeScript, focused ESLint, Ruff, format, and
-pinned mypy 1.13 clean. Normal publication and dependency-ordered propagation
-remain separate gates.
-
-## 2026-08-10 Workspace child receives second repaired parent
-
-PR `#4279` retains branch `feat/4218-toolstrip-workspace` and base
-`feat/4181-launch-monitor-registry`. It normally merges exact repaired parent
-head `12dd76a8dbcc106c4683f2f2e53076f8dc6f1b76`; there is no feature-code
-conflict, rebase, retarget, or history rewrite. The inherited explicit ndarray
-boundaries do not alter numerical behavior. Fresh child CI, review, and
-dependency order remain required.
-Verification after reconciliation is 25 focused D-plane/impact tests plus
-docs-governance, changed-file-size, and whitespace gates.
-
-## 2026-08-10 Workspace child receives exact repaired parent
-
-PR `#4279` keeps branch `feat/4218-toolstrip-workspace` and base
-`feat/4181-launch-monitor-registry`. Its original head
-`05383d333b6fd87eaf5e37305476f50b505c2c2e` normally merges exact parent
-`31cbc007d4c85b5479b7cd0fb0969124eab2af67` in that order. The combined
-shell retains the child's top toolstrip, persistent module visibility,
-reorderable workspace, granular playback, path trail, and independent plot
-controls. Parent repairs remain additive: the workspace mixin reuses the
-canonical navigation constants, and the simulation controls reuse the single
-persisted `ImpactLayerControls` checkbox map without duplicating UI state.
-
-Focused and broad verification is green: 1,339 Python tests pass with six
-explicit optional/Rust-wheel skips; 545 React tests pass, as do type-check,
-lint, and production build. Forty navigation/simulation GUI tests pass after
-the final formatting change. Exact-parent Ruff/Ruff-format/Black, pinned MyPy
-1.13 for 18 production modules, Bandit, file-size, docs, minimum-test,
-assertion, detect-secrets, diff, CPython 3.10.20 compilation/import, and 30
-compatibility regressions pass. There is no Rust delta from the exact parent.
-The merge commit must keep this file, the root handoff, campaign handoff, and
-`SPEC.md` together. Independent staged review found no actionable findings
-after 76 additional focused PyQt/navigation/workspace tests; exact-head
-protected CI and required review remain release gates after a guarded ordinary
-push.
-
-## 2026-08-10 Workspace fractional-timestamp compatibility repair
-
-The Python 3.10 lane on descendant PR #4281 revealed that the strict workspace
-ordering test reached `datetime.fromisoformat` with a one-digit fractional
-second. Python 3.10 rejects that spelling before comparing timestamps, although
-newer supported interpreters accept it. PR #4279 is the earliest owning branch.
-The workspace validator now enforces one anchored UTC grammar and parses every
-losslessly representable zero- to six-digit fraction consistently, rejecting
-greater precision rather than allowing interpreter-dependent truncation. It
-does not modify the persisted spelling, UTC requirement, schema, or ordering
-rule.
-
-Evidence is `778 passed` for the full Rate suite, `45 passed` across the
-compatibility and workspace document tests on the local interpreter, and
-`27 passed` under real CPython 3.10.20. Ruff, format, pinned mypy 1.13, docs
-governance, and the 400-line budget pass. Keep this handoff, the root handoff,
-campaign handoff, and SPEC entry in the same implementation commit; verify the
-exact remote head before a normal push and propagate through later descendants.
-
-## 2026-08-09 Universal Variation Visualization Continuation
-
-Branch `feat/4144-variation-export-continuation` remains based on
-`feat/4218-toolstrip-workspace` and now contains exact corrected parent
-`3f67ed466fefc8991db9c4409f921f25e1c37142` through the normal merge containing
-this handoff. The core PyQt6/React variation workspace has selectable
-input/contact/impact/shot scatter, a scatter matrix with marginals, landing
-dispersion, and an all-trial 3D swing-arc overlay with reference trace,
-principal spread, RMS variability, quiet zones, filtering, and linked trial
-selection.
-
-This continuation closes an export/accessibility parity gap: both clients now
-export the complete selected scatter axes as CSV, including every trial,
-typed outcome, and explicit unavailable values. PyQt now also exposes the raw
-selected-axis rows in a bounded read-only table. Shared table population is
-factored into `variation_trial_table.py`; the scalar scatter view is isolated
-in `variation_scatter_view.py`. Changed production modules remain below 400
-lines and changed functions remain at or below 50 lines.
-
-The continuation is published as draft PR #4280. Current exact local evidence
-on implementation commit `b3b09215e` is 890
-Python/PyQt/shared swing tests passed with one expected optional-Rust skip and
-15 existing warnings, and 89 React test files / 545 tests passed. Ruff,
-formatting, Black, targeted mypy, TypeScript, zero-warning ESLint, the 166-module
-Vite build, and `git diff --check` pass. This is local evidence only; no PR,
-protected CI, review, merge, or default-branch release has yet been established.
-
-The current local continuation normally incorporates exact corrected parent
-`3f67ed466fefc8991db9c4409f921f25e1c37142` while preserving #4280's
-`feat/4218-toolstrip-workspace` base. Its current focused evidence is `46`
-Python 3.11 tests and `19` real-Python-3.10.20 tests with PyQt6 installed,
-including the merged compatibility and variation widget contracts. React
-passes `1 file / 8 tests`, TypeScript, and focused zero-warning ESLint. Ruff,
-format, pinned mypy 1.13, documentation governance, ancestry/SPEC assertions,
-and diff checks pass. SPEC 1.14.11 is the unique child entry for the
-scatter-export and accessible-row-table source change. This propagation is
-local only and has not been pushed.
-
-Literal audit of "every many-trial simulation" found two dependent gaps that
-must remain explicit:
-
-- wind-strategy uncertainty retains paired per-strategy outcomes in both
- runtimes but has no PyQt/React workflow and does not feed the universal
- scalar plot facade;
-- the capability optimizer stores aggregate statistics but discards the
- individual evaluation rows needed for honest scatter plots.
-
-Issue #4199 already owns the wind UI/scatter requirement. Its adapter must use
-composite row identity `(strategy_id, trial_index)`, retain completed,
-nonconverged, and invalid cohorts, and report that impact variables are
-unavailable because this runner begins at prescribed launch. Do not coerce it
-into the impact-specific cohort enum or fabricate impact/landing values.
-
-Branch `feat/4199-wind-scalar-adapter` is published as
-[draft PR #4281](https://github.com/D-sorganization/Tools/pull/4281), stacked
-on exact corrected draft PR #4280 head
-`38ed58cab96842a3007e76a855db83ee2452b8fd`. That parent is incorporated by a
-normal local merge while preserving base
-`feat/4144-variation-export-continuation`; no branch was rebased, retargeted,
-force-pushed, or published by this continuation.
-Implementation commit `4a28114aa` supplies that first UI-neutral model slice.
-Python and React share the exact
-snake-case `scalar-ensemble/v1` wire structure: structured provenance,
-labeled stages/categories/cohorts, unit-bearing variables, RFC3986 composite
-row identity, immutable nullable raw rows, and overall/per-cohort x/y/paired
-availability. The wind adapter validates deterministic request/analysis trial
-agreement, retains every actual and perfect-information status, and exposes
-true/estimated wind, launch/aim, target, landing, miss, cost, and information
-delta without invoking the flight solver. Impact variables remain honestly
-absent because this analysis begins at launch.
-
-The original broad local gates remain green: 906 Python/PyQt/shared-swing tests
-passed with one expected optional-Rust skip and 15 existing warnings; 91 React
-files / 555 tests passed. After corrected-parent propagation, focused evidence
-is `49 passed` on Python 3.11 and `49 passed` on real CPython 3.10.20 with
-PyQt6/scientific dependencies present, plus `2 React files / 10 tests`,
-TypeScript, and zero-warning focused ESLint. Ruff check/format passes all four
-child Python files; pinned mypy 1.13 passes both production modules and the
-wind-adapter test after its status helper received an exact `Literal` type.
-The function budget passed at that historical head, but the 403-line wind
-adapter did not satisfy the mandatory below-400 module ceiling; the 2026-08-11
-repair above is the first point at which that module claim is true. SPEC
-1.14.11 uniquely records the child change above parent 1.14.10. This
-contract/adapter does not complete #4199: the next slice still needs background
-execution, progress and cancellation, PyQt/React scatter/strategy UI,
-persistence, and export wiring.
-
-## 2026-08-07 Ground Model and Four-Surface Parity Revalidation
-
-The user's requested rolling-ground and site-wide parity programs already
-exist as [epic #4267](https://github.com/D-sorganization/Tools/issues/4267)
-with children #4268-#4276 and
-[epic #4260](https://github.com/D-sorganization/Tools/issues/4260) with
-children #4261-#4266. Do not create duplicate epics. A fresh repository and
-live-GitHub audit was recorded in
-[the ground comment](https://github.com/D-sorganization/Tools/issues/4267#issuecomment-5222725556)
-and [the parity comment](https://github.com/D-sorganization/Tools/issues/4260#issuecomment-5222726010).
-
-There is no qualified landing/bounce/roll implementation yet. The current
-airborne solvers stop at the relative launch plane and the shared
-`TrajectoryPoint` omits terminal angular velocity. For a teed shot, translating
-that relative trajectory into the course frame can leave the terminal ball
-center at tee elevation. Complete #4268 and #4269 before implementing or
-presenting bounce, roll, or total distance.
-
-Reuse the Tools `GroundModelResult` fail-closed boundary, putting skid/roll
-limiting cases, and turf provenance/variation/cancellation patterns. Adapt
-UpstreamDrift's split terrain material, elevation, normal, and region contracts
-through a one-way versioned DTO. Do not qualify Upstream's scalar landing
-helper, heuristic putting spin relaxation, legacy duplicate terrain model, or
-Rust `(1-friction)` contact law as production high-speed landing physics.
-
-The parity matrix must keep Rate and Upstream's separate products distinct:
-standalone Rate PyQt6/React, Upstream's Rate PyQt provider/React route, Shot
-Tracer PyQt6/React, and the legacy ball-flight GUI. Current Upstream `main`
-has no native Rate React route, and its Tools source resolvers disagree about
-vendor-first versus sibling-first precedence. A launcher tile cannot satisfy a
-calculation-parity row; #4261, #4262, and #4264 must make the runtime source,
-exact Tools pin, and support state machine-verifiable.
-
-## 2026-08-09 Workspace Python 3.10 compatibility completion
-
-The #4279 continuation now contains exact corrected parent
-`08a2fdd8ce6bbc8fbb8f121927a677d4addb6b11` through normal local merge
-`a340fabefa443d47325c5538f342683b38c01ade`, without rebasing, retargeting,
-force-pushing, or publication. The workspace command and view enums use the
-shared `StrEnum` runtime compatibility contract with native enum typing kept
-under `TYPE_CHECKING`; `_workspace_validation` uses the shared `UTC` value.
-Stable identifiers, enum values, UTC serialization, schemas, and behavior are
-unchanged.
-
-The combined regression inspects the runtime branch for all nine inherited
-and child string-enum modules plus both UTC modules and directly executes the
-three child workspace modules. Focused Python 3.11 evidence is `126 passed`.
-Real CPython 3.10.20 evidence is `14 passed` plus successful dotted imports of
-10 Rate/shared targets. Ruff check/format is clean, and pinned mypy 1.13 passes
-all 11 affected production files under the changed-file CI contract. Keep the
-root, tool, campaign handoffs and SPEC 1.14.9 entry in the implementation
-commit; protected CI and review remain required after a normal push.
-
-## 2026-08-09 Workspace stack parent propagation
-
-Draft PR #4279 keeps base `feat/4181-launch-monitor-registry`. Exact published
-parent head `08a2fdd8ce6bbc8fbb8f121927a677d4addb6b11` is carried by a normal
-merge without rebasing, retargeting, force-pushing, or publishing this local
-continuation. Source changes applied cleanly; overlapping handoff/specification
-history was reconciled monotonically. The result retains the parent's facade
-and Python 3.10 repairs plus the child's complete File/View/Tools registry,
-strict workspace document, matched PyQt6/React toolstrips, module
-visibility/order, playback, and independent plot controls.
-
-The reconciled ancestry passes `126` focused Python/PyQt tests and `8 React
-files / 32 tests`. Ruff check/format passes all 28 relevant Python files, and
-CI-pinned mypy 1.13 passes the 18 changed production files and both facade
-tests. Mypy caught an untyped Qt `isChecked()` result in the child's
-`legend_visible()` boundary; the method now returns an explicit `bool` without
-changing runtime behavior. The affected simulation GUI rerun is `29 passed`;
-documentation governance and diff checks pass. Keep this handoff, the root
-handoff, the campaign handoff, and `SPEC.md` together in the merge commit.
-
-## 2026-08-10 Second D-Plane Parent Repair Propagation
-
-Draft PR `#4203` keeps base `feat/4189-dplane` and normally merges exact
-repaired parent head `7d8d2f06dc797021d01939691e58f8425b652b33` without
-rewriting either branch. The inherited change makes the two private D-plane
-NumPy return boundaries explicit for pinned MyPy while preserving numerical
-semantics, frames, schemas, and UI behavior. The parent quality gate is green;
-child protected CI, review, dependency order, and #4189 closure remain open.
-Post-reconciliation evidence is 25 focused D-plane/impact tests plus docs,
-changed-file-size, and whitespace gates. Local pinned-type evidence remains the
-parent's green hosted quality gate: Windows MyPy 1.15 encounters incompatible
-installed NumPy stub syntax and WSL is unavailable with `E_FAIL`, so neither
-local attempt is represented as green.
-
-## 2026-08-10 Launch-Registry Child Propagation
-
-Draft PR `#4203` (`feat/4181-launch-monitor-registry`) retains its
-`feat/4189-dplane` base and normally merges original child head
-`08a2fdd8ce6bbc8fbb8f121927a677d4addb6b11` with exact parent head
-`b443fdbed7064c5db0320106013c8413e3e24356`.
-
-The reconciliation preserves the child branch's responsive
-`SimulationViewControlsMixin` and delegates its persisted D-plane layer
-checkboxes to the parent's `ImpactLayerControls` helper. The compatibility
-mapping and helper mapping are the same object, which prevents duplicate state
-while retaining existing UI automation and persistence behavior. Both PyQt
-modules remain below the 500-line limit.
-
-The original child already exceeded the protected budget in swing sources,
-the plotting catalog, and the PyQt main window. Focused modules now own the
-triple-pendulum model, immutable plotting-variable contract, and versioned tab
-state. Compatibility imports remain the same objects, while the former
-monoliths fall to 282, 459, and 494 lines. Focused evidence is green across 36
-PyQt simulation/layout tests, 38 plotting/navigation tests, and 21 simulation
-source/export tests. Combined verification is green across 1,249 Python tests
-with six explicit skips, 521 React tests and all web gates, 12 Rust tests,
-real CPython 3.10 checks, scoped Ruff/Black/pinned MyPy, and repository
-governance/security checks. The changed-file 500-line gate passes all 107
-candidate files. A full-tree audit still reports untouched `kinetics.py` and
-`torque_profile_panel.py`; neither differs in this propagation. Independent
-staged review found no actionable findings after 95 additional focused tests.
-Current-head protected CI and required repository review remain release gates.
-
-## 2026-08-09 Python 3.10 enum import repair
-
-PR #4203 now owns the earliest fix for seven inherited Rate/shared swing
-modules that imported Python 3.11's `enum.StrEnum` directly. Runtime code uses
-the established shared compatibility helper while mypy sees the native enum
-only inside `TYPE_CHECKING`. This preserves wire values and enum semantics on
-supported interpreters and lets the repository's hosted Python 3.10 lane
-collect the modules. The focused evidence is 64 tests, Ruff/format, pinned
-mypy 1.13 across eight changed files, and a real CPython 3.10.20 source/runtime
-probe. The exact published #4203 head is
-`ab7de5a47977417e02926c3fbc7476002e82b690`; propagate it through the existing
-stack without changing bases.
-
-A follow-up scan found the torque-profile controller importing
-`datetime.UTC` directly. That parent-owned Python 3.11 boundary now uses
-`shared.python.compatibility.UTC`; persisted timestamps and torque-profile
-behavior are unchanged. Re-run the focused torque-profile UI tests and the
-real Python 3.10 compatibility probe before propagation.
-
-## 2026-08-09 Launch-registry parent CI repair
-
-PR #4203 exact-head run `31199764932` reached the Python test lanes but failed
-during Linux collection, before behavioral assertions. The two in-package
-flight/solver facade tests were collected as `src.shared...` modules while
-their absolute aliases crossed into the editable `shared...` namespace. They
-now import their sibling facade package relatively, preserving the pinned
-public API contract and production behavior. Reproduce with pytest
-`--import-mode=importlib`; keep the separate Rust missing-`libpython3.11`
-failure classified as runner infrastructure. Publish normally and propagate
-the repaired parent through the existing stack without changing PR bases.
-Verification is `12 passed` on Windows and `12 passed` on WSL Python 3.11
-under importlib collection; Ruff/format and exact mypy 1.13 pass for both
-changed modules. The dataclass metadata assertion remains active behind an
-explicit test-only `Any` introspection boundary.
-
-## 2026-08-10 PR #4202 D-plane ndarray typing repair
-
-On top of verified published head
-`b443fdbed7064c5db0320106013c8413e3e24356`, the two private D-plane ndarray
-helpers now bind NumPy results to explicit ndarray locals before returning
-them. This closes the exact MyPy 1.13 `no-any-return` findings from CI Standard
-run `31384810375`, job `93442745760`, without changing numerical operations,
-DbC validation, reference frames, persistence, rendering, or public contracts.
-
-The exact MyPy failure was reproduced before editing and is green after the
-repair. Twenty-four focused D-plane and impact integration tests pass, along
-with seven metadata/pre-push contract tests, scoped Ruff, Ruff format, Black,
-docs governance, minimum-test, module-size, changed-file-size, and diff checks.
-Three unrelated CI-workflow contract tests still expect later toolcache/env
-steps not present on this older branch; no workflow file is in scope. This
-local commit does not push, retarget, change draft state, or claim issue
-completion; protected CI, review, and parent-first release order remain
-mandatory.
-
-## 2026-08-10 D-Plane Child Propagation
-
-Draft PR `#4202` (`feat/4189-dplane`) retains its
-`feat/4162-wedge-impact-visualization` base and normally merges original child
-head `b4abec03bccfbdd87ddf91427159c5c2332c21dd` with exact parent head
-`6704a3e541a3e74c28b4a284530d1a21269dd340`. The inherited Python 3.10 UTC
-repair and AST guard remain intact beside the frame-explicit D-plane contract.
-
-Persisted D-plane layer controls now live in a focused helper so
-`simulation_view.py` again satisfies the protected 500-line budget while
-retaining the existing UI-automation compatibility seam. Combined verification
-is green: 93 focused and 825 scoped Python tests (two optional `build123d`
-skips), 360 React tests and all web gates, real CPython 3.10.20
-compilation/UTC, scoped Ruff/Black/MyPy, and repository governance gates. The
-exact parent's 12 unchanged `swing-core` tests remain applicable because this
-child has no Rust delta. The 17-error broad MyPy Qt/NumPy baseline in 11
-untouched files remains separate. Protected CI and required review remain
-release gates.
-
-## 2026-08-10 Impact-Visualization Child Propagation
-
-Draft PR `#4179` (`feat/4162-wedge-impact-visualization`) retains its
-`feat/4166-wedge-turf-physics` base and normally merges original child head
-`0eb804e70887c788421332369e42792411aff55a` with exact parent head
-`bfa83aedc88ead380babc73a699377d98b971006`. The inherited Python 3.10 UTC
-repair and AST guard remain intact beside the exact-event scene contract.
-
-Combined verification is green: 58 focused and 739 scoped Python tests (two
-optional `build123d` skips), 347 React tests and all web gates, real CPython
-3.10.20 compilation/UTC, scoped Ruff/Black/MyPy, and repository governance
-gates. The exact parent's 12 unchanged `swing-core` tests remain applicable
-because this child has no Rust delta. The 17-error broad MyPy Qt/NumPy baseline
-in 11 untouched files remains separate. Protected CI and required review
-remain release gates.
-
-## 2026-08-10 Turf-Physics Child Propagation
-
-Draft PR `#4178` (`feat/4166-wedge-turf-physics`) retains its
-`feat/4161-wedge-ground-clearance` base and normally merges original child
-head `aaae3f73e17dbfaad5cca1dc6f49559b3aebe9d5` with exact parent head
-`9ea93e92563280ec34bca682ad44d7409edd7a02`. The inherited Python 3.10 UTC
-repair and AST guard remain intact beside the provenance-gated turf model.
-
-Combined verification is green: 56 focused and 732 scoped Python tests (two
-optional CAD-dependency skips), real CPython 3.10.20 checks, scoped
-Ruff/Black/MyPy, and repository governance gates. The unchanged TypeScript and
-Rust surfaces retain the exact parent's green 345 React and 12 Rust test
-evidence. The 17-error broad MyPy Qt/NumPy baseline in 11 untouched files
-remains separate. Protected CI and required review remain release gates.
-
-## 2026-08-10 Ground-Clearance Child Propagation
-
-Draft PR `#4174` (`feat/4161-wedge-ground-clearance`) keeps its
-`feat/4163-impact-inspector` base and normally merges original child head
-`880a6465fc872cf3d6650283db154ddc41793a31` with exact parent head
-`9ddaff3b6bca542fd7a2befc7d7b0ae53910a60a`. The inherited Python 3.10 UTC
-repair and AST guard remain intact beside the ground-clearance analysis.
-
-Combined verification is green: 56 focused and 703 scoped Python tests (two
-optional `build123d` skips), 345 React tests and all web gates, 12 Rust tests,
-real CPython 3.10.20 compile/UTC checks, scoped Ruff/Black/MyPy, and repository
-governance checks. The existing 17-error broad MyPy Qt/NumPy baseline across
-11 untouched files is documented, not expanded. Current-head protected CI and
-required review remain pending.
-
-## 2026-08-10 Python 3.10 Repair Propagation
-
-Draft child PR `#4173` (`feat/4163-impact-inspector`) retains its
-`feat/4144-variation-visualizations` base and normally merges original child
-head `3c43955aaeb3964ff8c3ef2748d626baae518b76` with exact parent head
-`22b66b560652b78de84141344c4ddd9a92a83b26`. This carries the shared
-Python 3.10-compatible UTC export and the source-wide AST guard into the wedge
-impact inspector without changing the persistence schema or user-visible
-timestamp format.
-
-Combined-stack verification is green across 63 focused Python tests, all 562
-Rate tests, all 334 React tests, TypeScript/ESLint/Vite gates, 12 `swing-core`
-tests, real CPython 3.10.20 compile/UTC checks, Ruff/Black, focused pinned MyPy
-1.13, and repository governance checks. The broad MyPy sweep retains 17
-pre-existing Qt/NumPy typing findings in 11 untouched files. The PR must remain
-draft until its exact-head protected checks complete and required review
-approves. Do not retarget, rewrite, force-push, admin-merge, or count
-infrastructure failures as passing evidence.
-
-## 2026-08-05 Advanced Wedge Impact Visualization
-
-Branch `feat/4162-wedge-impact-visualization` extends issue #4162 on top of the
-validated turf stack. It corrects the impact adapter to evaluate pose, twist,
-and articulated wrist geometry at the exact event time rather than silently
-using the nearest retained sample. The new versioned
-`rate-of-closure.impact-scene/v1` contract carries complete scene geometry,
-velocity components, metric equations, frames, assumptions, availability, and
-screw-axis data without placing physics in either UI.
-
-PyQt6 adds an exact-event Impact Inspector layer, locked physical axis scaling,
-isometric/face-on/down-the-line cameras, and 300-DPI PNG, vector SVG, and strict
-JSON export. React adds an orbitable and keyboard-controllable impact still,
-the same named cameras and velocity toggles, visibly expandable engineering
-metric definitions, and device-resolution PNG, true-primitive SVG, and JSON
-exports. The web mirror now retains and shortest-arc interpolates the canonical
-head rotation; the older limitation note saying it lacked full head pose is no
-longer accurate for this branch.
-
-Scientific boundaries remain explicit: articulated sources do not yet have an
-independent torsional head state; the scene is rigid-body instantaneous
-kinematics; illustrative turf profiles cannot support optimal-bounce or
-forgiveness claims; and turf force is not replayed into the retained swing.
-
-Current-head verification: all 576 Rate Python/PyQt tests passed (one existing
-polynomial-generator legend warning); all 347 React/model tests passed; the
-production Vite build, TypeScript, ESLint, Ruff, formatting, changed-module
-strict mypy, and protected module-size budget passed. Headless Chrome visual QA
-at 1600×1400 exercised named views, a vector toggle, keyboard orbit, and an
-expanded metric definition with zero console exceptions/log errors. The new
-web branch is running at `http://localhost:5260/`; the current PyQt process was
-also launched successfully and remained responsive.
-
-## 2026-08-05 Wedge Impact Inspector Integration
-
-Draft PR #4173 (`feat/4163-impact-inspector`) integrates the draft variation
-branch with the shared golf-club stack through wedge kinematics PR #4172. It
-adds the first bounded implementation slice for wedge epic #4158 /
-impact-inspector issue #4163:
-
-- Canonical inspection time and event label on every `SimulationRun`: impact
- for hits, closest approach for misses.
-- Exact `Jump to Impact` / `Jump to Closest Approach` controls in PyQt6 and
- React, with playback paused before the jump.
-- `simulation/impact_kinematics.py`, which adapts retained pose/twist/contact
- data to `shared.python.golf_club.WedgeKinematicState` and preserves geometry
- provenance and model limitations.
-- Engineering readouts in both clients for contact/reference AoA, remove-shaft
- counterfactual, shaft rotation and vertical velocity, face-normal rate,
- leading-edge/arc rate where available, and screw-axis distance.
-- Restored manual angular velocity in the React simulation path; the previous
- hard-coded zero made all closure and shaft metrics false zeros.
-- Deterministic midpoint tie-breaking for a flat maximum-speed plateau, so the
- manual source's automatic event is its documented square pose at 30 ms.
-
-Physics boundary: articulated pendulum runs expose the measured wrist-to-head
-shaft line but have no shaft-twist degree of freedom. The inspector reports
-that absence rather than inventing torsional motion. The web mirror still does
-not retain full head pose; its readout declares that limitation until WASM or a
-canonical backend replaces the temporary TypeScript mirror.
-
-Current-head release evidence: 1,006 Python/PyQt/shared-swing tests passed with
-five optional Rust-wheel parity skips; 334 React/model tests and 12 swing-core
-Rust tests passed; Vite production build, TypeScript, ESLint, Ruff, formatting,
-and mypy across 165 source files passed. A focused post-refactor PyQt run passed
-46 tests. Browser QA verified the 1,307 deg/s manual fixture at 30 ms and a
-1.430 s closest-approach miss with zero console warnings/errors. Native-window
-QA confirmed the control and readout are visible in the standalone PyQt6 app.
-
-## Status Note
-
-`src/rate_of_closure` and `src/shared/python/swing_sim` do **not exist on
-`main` yet** — they land with PR #4119. This doc describes the tool as it
-exists on the in-flight branch stack (`feat/impact-simulation-platform` →
-`feat/investigation-suite` → `feat/course-showcase`) so the next agent has
-full context the moment #4119 merges. If you're reading this on a fresh
-`main` checkout and don't see `src/rate_of_closure/`, check out one of those
-branches or wait for #4119 to land.
-
-## Where This Tool Is Headed
-
-Rate of Closure started as a single-page "closure rate" calculator (twist
-model: GC-path vs impact-point-path gap, °/ft). Epics #4103 → #4120 → #4125 →
-#4130 are growing it into a full swing → impact → ball-flight simulator with
-PyQt6 + web parity and eventual public GitHub Pages distribution. Read
-`src/rate_of_closure/README.md` (frame conventions, Cheetham dossier sourcing,
-run instructions) before touching physics code.
-
-## The #4119 → #4124 → #4129 PR Stack
-
-Each PR consolidates a whole epic's stacked feature branches into one PR to
-keep self-hosted CI load down (see `CLAUDE.md` — these are big diffs).
-
-- **#4119** `feat/impact-simulation-platform` (epic #4103, open, auto-merge
- armed). Base tool (twist model, PyQt6 + React/Vite web, Cheetham dossier
- data) + STL clubheads/club library/inertial model + `swing_sim` shared
- package (`src/shared/python/swing_sim/`: swing sources, impact model ported
- from UpstreamDrift with 3 physics fixes, gear effect, 7 literature
- ball-flight models, goal-driven multi-start solver) + `swing-core` Rust
- crate (pyo3 + wasm) + app integration (simulation session, impact-time
- scrubber, screw-axis overlay via the rotation_converter adapter, video
- controls, CSV/JSON export, solver panel). 404 pytest + 72 vitest + 111
- cargo tests, all local gates green. Supersedes #4092/#4097/#4098/#4112-4118.
-
-- **#4124** `feat/investigation-suite` (epic #4120, open, **draft state —
- do not merge yet**, stacked on #4119). Adds `rate_of_closure/plotting/`
- (40-variable data catalog, `PlotSpec`, Plots tab + custom-plot wizard),
- scale-separated Strike/Swing/Flight viewers + standalone Flight Explorer,
- `swing_sim/variation/` (seeded Monte Carlo/NoiseSpec engine, dispersion +
- Spearman sensitivity, Variation tab), and V4: glossary (60 terms),
- cold-user help system, "Derivation & Traceability" → "Calculation
- Description" rename, full-model derivations, hover-hint completeness sweep.
- Supersedes draft PRs #4121/#4122/#4123. 566 pytest + 125 vitest passing.
-
-- **#4129** `feat/course-showcase` (epic #4125, open, **draft state — do
- not merge yet**, stacked on #4124). Merges `feat/realistic-heads` (H1:
- parametric club-type geometry, volumetric COG via divergence theorem),
- `feat/swing-kinetics` (H2: joint torque/force plots + 3D overlays from
- pendulum inverse dynamics), `feat/putting-vertical` (H3: `swing_sim`
- putting module + app Putting tab), then adds on top: H7 course scene
- (`ui/course.py` / `course_scene.py`) + target optimization
- (`swing_sim/solver/targets.py`, `TargetRegion`, `ImpactGoal.target_region`),
- and H6 showcase styling (`ui/pyqt6/app_style.py`, UpstreamDrift launcher
- visual language) + yards-default distance units. 413 pytest + 309 swing_sim
- - 174 vitest passing. H4 (AffineDrift putting research content) and H5
- (public release-management repo) are cross-repo and tracked in #4125
- directly, not in this PR.
-
-**Do not merge #4124 or #4129 before their base merges** — SPEC.md sections
-were unioned assuming sequential merge order; merging out of order will
-produce conflicting/duplicate changelog rows.
-
-## swing_sim Packages
-
-`src/shared/python/swing_sim/` (introduced by #4119, home for physics shared
-with UpstreamDrift via the established shared-module arrow):
-
-- `swing_sim/flight/` — 7 literature ball-flight models (drag/lift/spin
- decay), citations in registry metadata.
-- `swing_sim/impact/` — impact model ported from UpstreamDrift (offset-drop
- fix, opt-in 3×3 MOI tensor, inverted friction spin axis fix), gear effect,
- `SpringDamperImpactModel` (Kelvin-Voigt contact force history, 1e-7s steps)
- — this is the contact-force law epic #4130 will extend for the full
- contact-interval integration rather than duplicate.
-- `swing_sim/solver/` — goal-driven multi-start least-squares solver;
- `targets.py` (added in #4129) adds `TargetRegion` for green/fairway
- optimization goals.
-- `swing_sim/variation/` (added in #4124) — namespaced variable registry,
- `NoiseSpec`/`VariationPlan`, seeded parallel N-run Monte Carlo engine,
- dispersion/OAT sensitivity/Spearman/landing-ellipse stats.
-
-Epic #4130 (Impact-Interval Club Dynamics) will add `impact_interval/` to
-this same package — its home is explicitly `swing_sim` so UpstreamDrift
-reaches it via vendor, per that epic's F2 phase description. Not started yet
-(foundation-only epic, no PR).
-
-## How #4103/#4120/#4125/#4130 Relate to This Tool
-
-All four are rate_of_closure epics specifically (unlike the wider-monorepo
-epics tracked in the root `AGENT_HANDOFF.md`, e.g. SCADA #4085-#4089).
-#4103 is the foundation platform; #4120, #4125 are sequential feature waves
-stacked directly on its PR; #4130 is a physics-depth epic that extends the
-impact model #4103 introduced (contact-interval integration replacing the
-instantaneous-impulse approximation) — foundation phase only so far.
-
-## Web Mirror + GitHub Pages
-
-The web mirror (`src/rate_of_closure/web/`, React/Vite/TS) is pinned
-test-for-test against the PyQt6 model today (TS mirrors hand-written, not yet
-WASM — that swap is explicitly deferred to Phase 7 of #4103). It builds to a
-static bundle (`npm run build`) and carries Tauri scripts for desktop
-packaging, same as other web tools in the repo.
-
-**There is no automated GitHub Pages CI deploy for this tool yet.** No
-`.github/workflows/*.yml` references `rate_of_closure` or Pages deploy
-actions as of this writing. The only Pages-publishing precedent in the repo
-is `src/web_applications/unit_converter/unit-converter-app/DEPLOYMENT.md`'s
-manual branch-folder publish (Settings → Pages → select branch/folder).
-Phase 7 of #4103 ("GitHub Pages mirror updated (public share link), parity
-tests as deploy gates") owns building a real workflow — do not improvise one
-in an unrelated PR.
-
-## Must-Read Architecture Pointers
-
-1. `src/rate_of_closure/README.md` — frame conventions, unit conventions,
- dossier sourcing, run/build instructions.
-2. `src/rate_of_closure/model.py` (base twist physics, no Qt) once #4119
- lands.
-3. `src/shared/python/swing_sim/impact/` — the contact-force law shared
- with (and about to be extended by) epic #4130.
-4. `rust_core/swing-core/` — pendulum EOM + plane projection, pyo3 + wasm
- targets, follows the `tools-core` feature-contract pattern.
-5. `.github/workflows/maturin-swing-core.yml` (added by #4119) — Rust wheel
- build for this crate.
-
-## Gate Commands (this tool)
-
-```bash
-python3 -m pytest tests/rate_of_closure src/shared/python/swing_sim -n auto --timeout=60
-cd src/rate_of_closure/web && npm run test && npm run build && npx tsc --noEmit && npx eslint .
-cargo test -p swing-core
-python3 -m ruff check src/rate_of_closure src/shared/python/swing_sim
-python3 -m mypy src/rate_of_closure src/shared/python/swing_sim
-```
-
-Run Ruff format/check and pinned delta mypy on every changed Python file. Do not
-rewrite parents, force-push, bypass checks, infer unavailable values, or close
-#4201 until exact protected merge, installed package, downstream pin, science,
-performance, accessibility, documentation, and rollback evidence all exist.
-
-## 2026-08-11 parent sections preserved during #4282 reconciliation
-
-## 2026-08-11 Workspace child receives hosted MyPy repair
-
-PR `#4279` retains branch `feat/4218-toolstrip-workspace` and base
-`feat/4181-launch-monitor-registry`. Exact child
-`7806a16f58e1c6999d32f0127a187fbb21f839a1` normally merges exact published
-parent `3796b49e40b677fbac4e05739f8be49f905df2cb`. No feature-code conflict
-exists: the inherited production delta is four static `numpy.ndarray` casts,
-while workspace/toolstrip behavior and runtime arrays, physics, frames, units,
-imports, and UI behavior remain unchanged. This local merge does not satisfy
-fresh protected CI, required review, unresolved-thread, dependency, or release
-gates.
-
-## 2026-08-11 workspace child receives latest repaired parent
-
-PR `#4279` retains branch `feat/4218-toolstrip-workspace` and base
-`feat/4181-launch-monitor-registry`. A normal merge incorporates exact parent
-`0216a547aa79727091a2939b96e779e8ddbd7304` into exact child
-`61b7f48b5aeb7d57246b4963da3df086e79cbe15`. There are no feature-code
-conflicts: workspace/toolstrip, visibility, navigation, playback, and plot
-behavior remain unchanged while the parent kinetics façade/dynamics/series
-split and pinned formatting are inherited. This local merge does not satisfy
-fresh protected CI, required review, unresolved-thread, dependency, or release
-gates.
-
-## 2026-08-11 Append-only SPEC preservation repair
-
-Independent review found that the local #4203 reconciliation omitted four
-exact D-plane parent SPEC rows dated 2026-08-10 (versions 1.13.11, 1.13.9,
-1.13.7, and 1.13.6). They are restored verbatim in a documentation-only
-follow-up. Production behavior, tests, ordered parents, base, and local quality
-evidence are unchanged; re-review, normal publication, and protected CI remain
-open.
-
-## 2026-08-11 Current D-plane parent reconciliation
-
-PR #4203's published child `217e36dc93d30f79826847f958fbcd10805e58ed`
-is being normally merged with exact current D-plane base
-`f3363aa88868f6a5c7e9ccfc682a9eca014e86c1`. The base and source branch stay
-unchanged. The only conflict is the parent's formatting of an older monolithic
-kinetics expression: the split facade keeps its typed pendulum accessor and
-inherits the parent's geometry explanation. No launch-monitor, D-plane, or
-kinetics behavior is intentionally changed. Four Qt-stub `Any` returns exposed
-by the exact MyPy 1.13 delta are also narrowed to their declared `bool`/`str`
-contracts without changing values. Focused/full validation, independent
-review, normal publication, and protected CI remain open.
-
-## 2026-08-11 Exact-head format completion
-
-Protected CI on #4203 head `7d69a545ae555679f0318940e67c1786626d6794`
-failed only Ruff formatting. The pinned 0.14.10 reproduction found eleven
-noncompliant changed Python files: four inherited files plus seven altered by
-the automated pre-commit repair. The pending repair intentionally changes no
-launch-monitor, kinetics, simulation, or UI behavior and requires independent
-review plus fresh protected CI before integration.
-
-## 2026-08-11 Hosted MyPy NumPy-return repair
-
-CI Standard run `31477542889`, job `93734652129`, found four
-`no-any-return` errors after the kinetics façade extraction at exact PR #4203
-head `0216a547aa79727091a2939b96e779e8ddbd7304`. The NumPy stubs widen
-`linalg.norm`, `concatenate`, and matrix projection results to `Any` even
-though the runtime operations return arrays. The private series/dynamics
-modules and public façade now use explicit `cast(np.ndarray, ...)` boundaries.
-These casts are static only: array identity, values, dtype, shape, physics,
-frames, units, imports, and UI behavior are unchanged. Verification must cover
-the complete PR changed-source MyPy set and both focused and full Rate tests.
-Current local evidence is 102 changed-source MyPy files, 28 focused tests, and
-all 701 Rate tests passing; complete-delta Ruff/format and Bandit are also
-green.
-
-## 2026-08-11 Kinetics façade extraction
-
-The strict current-head delta reproduces a protected size failure that the
-PR-base comparison hides: `kinetics.py` is changed versus `HEAD~1` and is 646
-LOC, above the ungrandfathered 500-LOC maximum. The public module is now a
-222-LOC run adapter/facade; its pure double-pendulum dynamics are in the
-205-LOC `_kinetics_dynamics.py`, and the immutable `KineticsSeries`/DbC
-contract is in the 131-LOC `_kinetics_series.py`. Existing public imports and
-the `_reaction_forces` seam are the same implementation objects. A RED-first
-identity test plus the existing physics, energy, force, parity-fixture,
-presentation, and PyQt tests protect behavior. No physics, frame, SI-unit,
-schema, UI, or stack-order change is intended; the commit remains local only.
-Focused kinetics/presentation/PyQt verification is 28 passing tests; the
-complete Rate-of-Closure Python regression suite is 701 passing tests.
-
-## 2026-08-11 #4203 pinned-Ruff formatting repair
-
-No material handoff change: current-head CI Standard run `31468208320`, job
-`93705508050`, identified eight files that differ from repository-pinned Ruff
-0.14.10 output. This commit changes formatting only; Rate physics, behavior,
-frames, persistence schemas, PyQt/React contracts, stack bases, and dependency
-order remain unchanged. Fresh protected CI and review are still required.
-
-## 2026-08-10 Ground/Tee parity child receives repaired parent
-
-Ready PR `#4325` keeps branch `feat/4143-tee-parity-fixture` and base
-`feat/4181-launch-monitor-registry`. It normally merges exact repaired parent
-head `12dd76a8dbcc106c4683f2f2e53076f8dc6f1b76` without any production/test
-code conflict or history rewrite. Shared parity and rendered-evidence
-contracts remain intact; fresh protected CI, review, dependency order, and
-#4143 release remain open.
-
-## 2026-08-10 #4143 Python/React Golden Ball-Setup Parity
-
-The isolated `feat/4143-tee-parity-fixture` child begins at exact draft PR
-#4203 head `31cbc007d4c85b5479b7cd0fb0969124eab2af67`. One versioned JSON fixture now
-drives both Python and React ball-support tests with explicit SI units and the
-ground-plane-to-ball-bottom height reference. The shared cases cover Driver
-and non-Driver defaults, user overrides, Ground zero effective height,
-derived ball-center geometry and serialization, negative/NaN/infinite height
-rejection, and backward-compatible migration of a legacy run without
-`ball_setup`.
-
-Evidence is 18 passing Python tee/parity tests and 24 passing React
-tee/persistence/parity tests, plus green TypeScript, ESLint, Vite production
-build, Ruff check, and Ruff format. Production model and UI code are unchanged.
-Recorded visual evidence now adds 1600 x 1200 Playwright Driver/Tee and
-rerun-Ground captures plus 1400 x 900 hidden-window PyQt captures. The browser
-run asserts control state, diagram geometry, and zero console/page errors; the
-desktop run asserts canonical center/artist state, nonblank output, and
-different Ground/Tee digests without pixel absolutes. The exact artifacts and
-versioned manifests are in
-`C:\Users\diete\AppData\Local\Temp\rate-4143-visual-evidence-8050eeba`.
-Do not close #4143: protected current-head CI/review and release to `main`
-remain. This exact parent predates the strict campaign manifest on a divergent
-branch, so no downstream manifest was copied into this bounded child.
-
-## 2026-08-10 Wind scalar child receives second repaired parent
-
-PR `#4281` retains branch `feat/4199-wind-scalar-adapter` and base
-`feat/4144-variation-export-continuation`. It normally merges exact repaired
-parent `b90e5021a59e2081415b51ef29fbed06377bc201` without scalar-adapter code
-conflict or history rewrite. Fresh child CI, review, and dependency order
-remain required.
-Post-reconciliation evidence is 25 focused D-plane/impact tests plus docs,
-changed-file-size, and whitespace gates.
-
-## 2026-08-10 Variation export child receives exact workspace parent
-
-PR `#4280` retains branch `feat/4144-variation-export-continuation`, base
-`feat/4218-toolstrip-workspace`, and original child first parent
-`f90836e342efc8be624739802375af2876d11e5f`. Exact parent
-`6717e9e09d507dbc24bedb36177f1cdf0b4fd90b` merges normally as the second
-parent. All variation visualization/export source merged without conflict:
-selected scatter CSV, typed unavailable rows, accessible bounded raw tables,
-linked trials, focused PyQt widgets, and React parity remain additive with the
-parent workspace/toolstrip/playback/plot/navigation repairs. SPEC 1.14.12 is
-the unique combined child entry. Staged review exposed a stale linked-trial
-selection when a smaller rerun replaced the active result. Corrected PyQt
-views clear result-local selection before repopulating and validate all public
-setter indices; React clears on result identity change and shares only bounded
-selections with linked views. Thirty-seven focused variation tests and the
-complete Rate/shared-swing/golf-club matrix pass 1,528 tests with two explicit
-optional build123d skips; all 546 React tests across 90 files pass;
-TypeScript, ESLint, and production build are green. Exact-parent
-Ruff/Ruff-format/Black, pinned MyPy 1.13 across four Python production modules,
-Bandit, file-size, docs, minimum-test, assertion, detect-secrets, diff, real
-CPython 3.10.20 compilation, and 30 compatibility regressions pass. There is
-no Rust delta from the exact parent. Independent staged re-review found no
-actionable findings, including the first replacement-render React boundary.
-Protected CI/review remain release gates after an ordinary guarded push.
-
-## 2026-08-10 Variation child receives second repaired workspace parent
-
-PR `#4280` retains branch `feat/4144-variation-export-continuation` and base
-`feat/4218-toolstrip-workspace`. It normally merges exact repaired parent head
-`61b7f48b5aeb7d57246b4963da3df086e79cbe15` without feature-code conflict or
-history rewrite. Variation/export behavior remains unchanged; fresh child CI,
-review, and dependency order remain required.
-Post-reconciliation evidence is 25 focused D-plane/impact tests plus docs,
-changed-file-size, and whitespace gates.
-
-## 2026-08-10 Wind scalar child receives exact variation parent
-
-PR `#4281` keeps branch `feat/4199-wind-scalar-adapter`, base
-`feat/4144-variation-export-continuation`, and original child first parent
-`cf52529b1e68479321bb93b1be3d59c77f782008`. Exact parent
-`8bcc49fc4e16e5e43be0b7f0f03c3017d5b79d0c` merges normally second. The
-child's scalar-ensemble wire contract, provenance-preserving wind rows,
-availability accounting, and plot adapter remain additive with the parent's
-variation visualization/export and result-local selection repairs. Python and
-TypeScript reject wind scenarios unless their per-trial provenance is exact,
-shear/turbulence are zero, seed is zero, and gusts are empty. SPEC 1.14.13 is
-the unique combined child entry. Twenty-seven focused Python tests, the
-1,549-test complete Rate/shared-swing/golf-club matrix with two explicit
-optional build123d skips, and all 556 React tests across 92 files pass.
-TypeScript, ESLint, production build, Ruff/format, pinned MyPy, Bandit, size,
-docs, minimum-test, assertions, detect-secrets, diff, and CPython 3.10 compile
-gates pass. Independent re-review found no actionable findings after checking
-the exact provenance derivation and all five deterministic-scenario
-regressions; protected CI/review remain release gates.
-
-## 2026-08-10 Variation child timestamp propagation
-
-The #4280 continuation now carries exact parent
-`05383d333b6fd87eaf5e37305476f50b505c2c2e` through a normal merge while
-preserving its original base and complete variation export/accessibility
-implementation. The inherit…4250 tokens truncated…7417e02926c3fbc7476002e82b690`; propagate it through the existing
-stack without changing bases.
-
-A follow-up scan found the torque-profile controller importing
-`datetime.UTC` directly. That parent-owned Python 3.11 boundary now uses
-`shared.python.compatibility.UTC`; persisted timestamps and torque-profile
-behavior are unchanged. Re-run the focused torque-profile UI tests and the
-real Python 3.10 compatibility probe before propagation.
-
-## Do-Not List
-
-- Do not duplicate the Kelvin-Voigt contact-force law — #4130 requires
- `SpringDamperImpactModel` and the new `impact_interval/` package to share
- one implementation (DRY, explicit in the epic's binding standards).
-- Do not exceed 500 LOC per file in `rate_of_closure`, `swing_sim`, or
- `swing-core` — sub-package instead.
-- Do not hand-mirror physics into the TS web layer once WASM lands (Phase 7)
- — that's the whole point of the wasm-pack build; today's hand-written TS
- mirrors are a stopgap, not the target architecture.
-- Do not merge the stacked PRs out of order (see stack section above).
-- Do not invent citations in derivation docstrings or the AffineDrift
- putting research content (H4) — sourced/verifiable only, dossier
- discipline per epic #4125.
-
-## Roadmap (ordered)
-
-1. Merge #4119, then #4124, then #4129 in order.
-2. Start epic #4130 Phase F1 (formulation document) — six-DOF rigid-club
- contact-interval derivation, validation program design.
-3. Phase 7 of #4103: WASM swap + real Pages CI deploy workflow.
-4. #4125 H4/H5: AffineDrift putting research content and the public
- release-management repo (both cross-repo, not started).
diff --git a/src/rate_of_closure/application/__init__.py b/src/rate_of_closure/application/__init__.py
index 20fd60d88..cf3ca435d 100644
--- a/src/rate_of_closure/application/__init__.py
+++ b/src/rate_of_closure/application/__init__.py
@@ -6,6 +6,10 @@
CommandAvailability,
CommandUnavailableError,
)
+from .regional_surface_plan_files import (
+ read_regional_surface_plan_request,
+ write_regional_surface_plan_request_atomic,
+)
from .workspace_document import (
WORKSPACE_SCHEMA,
WORKSPACE_SCHEMA_VERSION,
@@ -30,7 +34,9 @@
"WorkspaceLayout",
"WorkspaceMetadata",
"read_workspace",
+ "read_regional_surface_plan_request",
"workspace_from_json",
"workspace_to_json",
"write_workspace_atomic",
+ "write_regional_surface_plan_request_atomic",
]
diff --git a/src/rate_of_closure/application/atomic_text_files.py b/src/rate_of_closure/application/atomic_text_files.py
new file mode 100644
index 000000000..852ce12b8
--- /dev/null
+++ b/src/rate_of_closure/application/atomic_text_files.py
@@ -0,0 +1,55 @@
+"""Small atomic UTF-8 text-file boundary shared by application documents."""
+
+from __future__ import annotations
+
+import os
+import tempfile
+from pathlib import Path
+
+
+def _destination_path(destination: str | Path, document_name: str) -> Path:
+ path = Path(destination)
+ if not path.name:
+ raise ValueError(f"{document_name} destination must name a file")
+ if not path.parent.is_dir():
+ raise FileNotFoundError(
+ f"{document_name} parent directory does not exist: {path.parent}"
+ )
+ if path.exists() and not path.is_file():
+ raise IsADirectoryError(f"{document_name} destination is not a file: {path}")
+ return path
+
+
+def write_utf8_text_atomic(
+ text: str,
+ destination: str | Path | None,
+ *,
+ document_name: str,
+) -> bool:
+ """Flush and atomically replace one UTF-8 text file.
+
+ ``None`` represents a cancelled chooser. Serialization must happen before
+ this function is called so a validation failure cannot touch the target.
+ """
+ if destination is None:
+ return False
+ if not isinstance(text, str):
+ raise TypeError("atomic file content must be text")
+ path = _destination_path(destination, document_name)
+ descriptor, temporary_name = tempfile.mkstemp(
+ prefix=f".{path.name}.", suffix=".tmp", dir=path.parent
+ )
+ temporary = Path(temporary_name)
+ try:
+ with os.fdopen(descriptor, "w", encoding="utf-8", newline="") as handle:
+ handle.write(text)
+ handle.flush()
+ os.fsync(handle.fileno())
+ os.replace(temporary, path)
+ except Exception:
+ temporary.unlink(missing_ok=True)
+ raise
+ return True
+
+
+__all__ = ["write_utf8_text_atomic"]
diff --git a/src/rate_of_closure/application/regional_surface_plan.py b/src/rate_of_closure/application/regional_surface_plan.py
index 34d5ecb89..1ffce376f 100644
--- a/src/rate_of_closure/application/regional_surface_plan.py
+++ b/src/rate_of_closure/application/regional_surface_plan.py
@@ -6,11 +6,13 @@
from dataclasses import asdict, dataclass
from shared.python.swing_sim.canonical_numeric_json import canonical_numeric_json
+from shared.python.swing_sim.ground.contract_types import GroundSurfaceProfile
from shared.python.swing_sim.ground.regional_plan_records import (
REGIONAL_PLAN_GEOMETRY_MODEL,
REGIONAL_PLAN_LIMITATIONS,
REGIONAL_PLAN_REQUEST_SCHEMA_VERSION,
GroundRegionalMaterialPlanRequest,
+ GroundRegionalMaterialRegion,
)
from shared.python.swing_sim.ground.regional_plan_wire import (
regional_material_plan_request_from_dict,
@@ -158,6 +160,99 @@ def _region_payload(region: RegionalOverlayDraft) -> dict[str, object]:
}
+def _surface_draft(surface: GroundSurfaceProfile) -> SurfaceMaterialDraft:
+ """Project one already-validated wire surface into editable SI values."""
+ return SurfaceMaterialDraft(
+ surface.surface_id,
+ surface.normal_restitution,
+ surface.static_friction,
+ surface.kinetic_friction,
+ surface.rolling_resistance,
+ surface.firmness_pa,
+ surface.hardness_fraction,
+ surface.grass_height_m,
+ surface.compressibility_fraction,
+ surface.compression_damping_fraction,
+ surface.turf_density_kg_m3,
+ surface.moisture_fraction,
+ )
+
+
+def _assert_editor_surface(surface: GroundSurfaceProfile) -> None:
+ """Reject material evidence not authored under the editor v1 contract."""
+ if (
+ surface.provider_id != EDITOR_PROVIDER_ID
+ or surface.provider_version != EDITOR_PROVIDER_VERSION
+ ):
+ raise ValueError("surface is not qualified by the editor provider v1")
+
+
+def _overlay_draft(region: GroundRegionalMaterialRegion) -> RegionalOverlayDraft:
+ return RegionalOverlayDraft(
+ region.region_id,
+ region.precedence,
+ region.lower_coordinate_m,
+ region.upper_coordinate_m,
+ _surface_draft(region.surface),
+ )
+
+
+def editor_draft_from_regional_surface_plan_request(
+ request: GroundRegionalMaterialPlanRequest,
+) -> RegionalSurfacePlanDraft:
+ """Project one fully validated, editor-qualified v1 request into the editor.
+
+ The editor provider v1 contract is explicitly unvalidated. Requests from a
+ different producer, material provider, axis qualification, or row capacity
+ are therefore rejected rather than relabelled or coerced.
+ """
+ if type(request) is not GroundRegionalMaterialPlanRequest:
+ raise TypeError("request must be an exact GroundRegionalMaterialPlanRequest")
+ provenance = request.provenance
+ if (
+ provenance.producer != EDITOR_PROVIDER_ID
+ or provenance.producer_version != EDITOR_PROVIDER_VERSION
+ ):
+ raise ValueError("request is not qualified by the editor producer v1")
+ if request.axis_origin_m != (0.0, 0.0, 0.0) or request.axis_unit != (
+ 1.0,
+ 0.0,
+ 0.0,
+ ):
+ raise ValueError("request uses an unsupported editor axis qualification")
+ if len(request.regions) > MAX_EDITOR_REGIONS:
+ raise ValueError(f"editor supports one to at most {MAX_EDITOR_REGIONS} regions")
+ _assert_editor_surface(request.base_surface)
+ for region in request.regions:
+ _assert_editor_surface(region.surface)
+ draft = RegionalSurfacePlanDraft(
+ request.request_id,
+ request.lower_coordinate_m,
+ request.upper_coordinate_m,
+ provenance.source_revision,
+ "unvalidated",
+ _surface_draft(request.base_surface),
+ tuple(_overlay_draft(region) for region in request.regions),
+ )
+ if provenance.input_sha256 != _source_digest(draft):
+ raise ValueError("editor provenance digest does not match the editable request")
+ return draft
+
+
+def regional_surface_plan_request_for_draft(
+ draft: RegionalSurfacePlanDraft,
+ imported_request: GroundRegionalMaterialPlanRequest | None = None,
+) -> GroundRegionalMaterialPlanRequest:
+ """Preserve an unchanged import exactly; otherwise bind fresh provenance."""
+ if imported_request is not None:
+ imported_draft = editor_draft_from_regional_surface_plan_request(
+ imported_request
+ )
+ if draft == imported_draft:
+ return imported_request
+ return validate_regional_surface_plan_draft(draft)
+
+
def validate_regional_surface_plan_draft(
draft: RegionalSurfacePlanDraft,
) -> GroundRegionalMaterialPlanRequest:
@@ -191,10 +286,14 @@ def validate_regional_surface_plan_draft(
__all__ = [
+ "EDITOR_PROVIDER_ID",
+ "EDITOR_PROVIDER_VERSION",
"MAX_EDITOR_REGIONS",
"RegionalOverlayDraft",
"RegionalSurfacePlanDraft",
"SurfaceMaterialDraft",
+ "editor_draft_from_regional_surface_plan_request",
"illustrative_regional_surface_plan_draft",
+ "regional_surface_plan_request_for_draft",
"validate_regional_surface_plan_draft",
]
diff --git a/src/rate_of_closure/application/regional_surface_plan_files.py b/src/rate_of_closure/application/regional_surface_plan_files.py
new file mode 100644
index 000000000..14ff29643
--- /dev/null
+++ b/src/rate_of_closure/application/regional_surface_plan_files.py
@@ -0,0 +1,57 @@
+"""Strict native file adapter for canonical regional surface-plan requests."""
+
+from __future__ import annotations
+
+from pathlib import Path
+
+from shared.python.swing_sim.ground.regional_plan_records import (
+ MAX_REGIONAL_PLAN_WIRE_BYTES,
+ GroundRegionalMaterialPlanRequest,
+)
+from shared.python.swing_sim.ground.regional_plan_wire import (
+ regional_material_plan_request_from_json,
+)
+
+from .atomic_text_files import write_utf8_text_atomic
+
+
+def _read_bounded_utf8(path: Path) -> str:
+ """Read one immutable handle snapshot without allocating beyond the cap."""
+ with path.open("rb") as handle:
+ raw = handle.read(MAX_REGIONAL_PLAN_WIRE_BYTES + 1)
+ if len(raw) > MAX_REGIONAL_PLAN_WIRE_BYTES:
+ raise ValueError("regional material plan exceeds maximum wire size")
+ try:
+ return raw.decode("utf-8")
+ except UnicodeDecodeError as exc:
+ raise ValueError("regional material plan must be valid UTF-8") from exc
+
+
+def read_regional_surface_plan_request(
+ source: str | Path,
+) -> GroundRegionalMaterialPlanRequest:
+ """Read and completely validate one canonical request before returning it."""
+ path = Path(source)
+ if not path.is_file():
+ raise FileNotFoundError(f"regional surface plan does not exist: {path}")
+ return regional_material_plan_request_from_json(_read_bounded_utf8(path))
+
+
+def write_regional_surface_plan_request_atomic(
+ request: GroundRegionalMaterialPlanRequest,
+ destination: str | Path | None,
+) -> bool:
+ """Write exact canonical request bytes, or return false after cancellation."""
+ if destination is None:
+ return False
+ if type(request) is not GroundRegionalMaterialPlanRequest:
+ raise TypeError("request must be an exact GroundRegionalMaterialPlanRequest")
+ return write_utf8_text_atomic(
+ request.to_json(), destination, document_name="regional surface plan"
+ )
+
+
+__all__ = [
+ "read_regional_surface_plan_request",
+ "write_regional_surface_plan_request_atomic",
+]
diff --git a/src/rate_of_closure/application/workspace_files.py b/src/rate_of_closure/application/workspace_files.py
index 58b6f2ebb..fa627902d 100644
--- a/src/rate_of_closure/application/workspace_files.py
+++ b/src/rate_of_closure/application/workspace_files.py
@@ -2,10 +2,9 @@
from __future__ import annotations
-import os
-import tempfile
from pathlib import Path
+from .atomic_text_files import write_utf8_text_atomic
from .workspace_document import (
WorkspaceDocument,
workspace_from_json,
@@ -13,18 +12,6 @@
)
-def _destination_path(destination: str | Path) -> Path:
- path = Path(destination)
- if not path.name:
- raise ValueError("workspace destination must name a file")
- parent = path.parent
- if not parent.is_dir():
- raise FileNotFoundError(f"workspace parent directory does not exist: {parent}")
- if path.exists() and not path.is_file():
- raise IsADirectoryError(f"workspace destination is not a file: {path}")
- return path
-
-
def read_workspace(source: str | Path) -> WorkspaceDocument:
"""Read and fully validate one workspace before returning it.
@@ -59,21 +46,7 @@ def write_workspace_atomic(
if destination is None:
return False
serialized = workspace_to_json(document)
- path = _destination_path(destination)
- descriptor, temporary_name = tempfile.mkstemp(
- prefix=f".{path.name}.", suffix=".tmp", dir=path.parent
- )
- temporary = Path(temporary_name)
- try:
- with os.fdopen(descriptor, "w", encoding="utf-8", newline="\n") as handle:
- handle.write(serialized)
- handle.flush()
- os.fsync(handle.fileno())
- os.replace(temporary, path)
- except Exception:
- temporary.unlink(missing_ok=True)
- raise
- return True
+ return write_utf8_text_atomic(serialized, destination, document_name="workspace")
__all__ = ["read_workspace", "write_workspace_atomic"]
diff --git a/src/rate_of_closure/ui/pyqt6/engineering_number_input.py b/src/rate_of_closure/ui/pyqt6/engineering_number_input.py
index ff0ed6d15..af130c734 100644
--- a/src/rate_of_closure/ui/pyqt6/engineering_number_input.py
+++ b/src/rate_of_closure/ui/pyqt6/engineering_number_input.py
@@ -16,6 +16,7 @@ class NumberInputSpec:
step: float = 0.1
minimum: float = -1e9
maximum: float = 1e9
+ decimals: int = 6
def __post_init__(self) -> None:
"""Reject unusable Qt ranges before a widget is constructed."""
@@ -25,6 +26,12 @@ def __post_init__(self) -> None:
raise ValueError("minimum and maximum must be finite")
if self.minimum > self.maximum:
raise ValueError("minimum must not exceed maximum")
+ if (
+ isinstance(self.decimals, bool)
+ or not isinstance(self.decimals, int)
+ or not 0 <= self.decimals <= 323
+ ):
+ raise ValueError("decimals must be an integer from zero through 323")
def engineering_number_input(
@@ -35,7 +42,7 @@ def engineering_number_input(
"""Create one consistently configured accessible SI number input."""
field = QDoubleSpinBox()
field.setAccessibleName(name)
- field.setDecimals(6)
+ field.setDecimals(spec.decimals)
field.setRange(spec.minimum, spec.maximum)
field.setSingleStep(spec.step)
field.setSuffix(spec.suffix)
diff --git a/src/rate_of_closure/ui/pyqt6/regional_surface_plan_io.py b/src/rate_of_closure/ui/pyqt6/regional_surface_plan_io.py
new file mode 100644
index 000000000..db39e5183
--- /dev/null
+++ b/src/rate_of_closure/ui/pyqt6/regional_surface_plan_io.py
@@ -0,0 +1,101 @@
+"""Native Open/Save As controller for the regional surface-plan editor."""
+
+from __future__ import annotations
+
+from pathlib import Path
+from typing import Protocol
+
+from PyQt6.QtWidgets import QFileDialog, QLabel, QPlainTextEdit, QWidget
+
+from rate_of_closure.application.regional_surface_plan_files import (
+ read_regional_surface_plan_request,
+ write_regional_surface_plan_request_atomic,
+)
+from shared.python.swing_sim.ground.regional_plan_records import (
+ GroundRegionalMaterialPlanRequest,
+)
+
+
+class RegionalSurfacePlanFileHost(Protocol):
+ """Minimal host surface needed by the native file controller."""
+
+ status_label: QLabel
+ readback: QPlainTextEdit
+
+ def current_request(self) -> GroundRegionalMaterialPlanRequest: ...
+
+ def apply_imported_request(
+ self, request: GroundRegionalMaterialPlanRequest
+ ) -> None: ...
+
+
+class RegionalSurfacePlanFileActions:
+ """Transactional native file commands with one successful recent path."""
+
+ def __init__(self, host: RegionalSurfacePlanFileHost, parent: QWidget) -> None:
+ self._host = host
+ self._parent = parent
+ self.recent_path: Path | None = None
+
+ def open(self) -> None:
+ """Choose, fully validate, and only then replace the editor draft."""
+ selected, _filter = QFileDialog.getOpenFileName(
+ self._parent,
+ "Open Regional Surface Plan",
+ self._initial_location(),
+ "JSON files (*.json)",
+ )
+ if not selected:
+ return
+ path = Path(selected)
+ try:
+ request = read_regional_surface_plan_request(path)
+ self._host.apply_imported_request(request)
+ except (OSError, TypeError, ValueError) as exc:
+ self._set_error(f"Open failed: {exc}")
+ return
+ self.recent_path = path
+ self._host.readback.setPlainText(request.to_json())
+ self._set_success(f"Opened {path.name}. No physics executed.")
+
+ def save_as(self) -> None:
+ """Validate before choosing a destination, then atomically replace it."""
+ try:
+ request = self._host.current_request()
+ except (TypeError, ValueError) as exc:
+ self._set_error(f"Save failed: {exc}")
+ return
+ selected, _filter = QFileDialog.getSaveFileName(
+ self._parent,
+ "Save Regional Surface Plan As",
+ self._initial_location("regional-surface-plan.json"),
+ "JSON files (*.json)",
+ )
+ if not selected:
+ return
+ path = Path(selected)
+ try:
+ write_regional_surface_plan_request_atomic(request, path)
+ except OSError as exc:
+ self._set_error(f"Save failed: {exc}")
+ return
+ self.recent_path = path
+ self._host.readback.setPlainText(request.to_json())
+ self._set_success(f"Saved {path.name} atomically. No physics executed.")
+
+ def _initial_location(self, filename: str = "") -> str:
+ if self.recent_path is None:
+ return filename
+ parent = self.recent_path.parent
+ return str(parent / filename) if filename else str(parent)
+
+ def _set_error(self, message: str) -> None:
+ self._host.status_label.setText(message)
+ self._host.status_label.setAccessibleName("Regional surface plan file error")
+
+ def _set_success(self, message: str) -> None:
+ self._host.status_label.setText(message)
+ self._host.status_label.setAccessibleName("Regional surface plan file success")
+
+
+__all__ = ["QFileDialog", "RegionalSurfacePlanFileActions"]
diff --git a/src/rate_of_closure/ui/pyqt6/regional_surface_plan_tab.py b/src/rate_of_closure/ui/pyqt6/regional_surface_plan_tab.py
index 26d8e7406..bcdc38ef3 100644
--- a/src/rate_of_closure/ui/pyqt6/regional_surface_plan_tab.py
+++ b/src/rate_of_closure/ui/pyqt6/regional_surface_plan_tab.py
@@ -2,13 +2,10 @@
from __future__ import annotations
-from collections.abc import Callable
from dataclasses import replace
-from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import (
QComboBox,
- QDoubleSpinBox,
QFormLayout,
QGroupBox,
QHBoxLayout,
@@ -17,7 +14,6 @@
QPlainTextEdit,
QPushButton,
QScrollArea,
- QSpinBox,
QVBoxLayout,
QWidget,
)
@@ -26,124 +22,23 @@
MAX_EDITOR_REGIONS,
RegionalOverlayDraft,
RegionalSurfacePlanDraft,
- SurfaceMaterialDraft,
+ editor_draft_from_regional_surface_plan_request,
illustrative_regional_surface_plan_draft,
- validate_regional_surface_plan_draft,
+ regional_surface_plan_request_for_draft,
)
-from rate_of_closure.ui.pyqt6.engineering_number_input import (
- NumberInputSpec,
+from rate_of_closure.ui.pyqt6.regional_surface_plan_io import (
+ RegionalSurfacePlanFileActions,
)
-from rate_of_closure.ui.pyqt6.engineering_number_input import (
- engineering_number_input as _number_input,
+from rate_of_closure.ui.pyqt6.regional_surface_plan_widgets import (
+ MaterialEditor,
+ RegionalOverlayRow,
+ coordinate_input,
)
-
-_MATERIAL_FIELDS = (
- ("normal_restitution", "Normal restitution", "", 0.01, 0.0, 1.0),
- ("static_friction", "Static friction", "", 0.01, 0.0, 5.0),
- ("kinetic_friction", "Kinetic friction", "", 0.01, 0.0, 5.0),
- ("rolling_resistance", "Rolling resistance", "", 0.01, 0.0, 1.0),
- ("firmness_pa", "Firmness", " Pa", 1_000.0, 0.001, 1e9),
- ("hardness_fraction", "Hardness", " fraction", 0.01, 0.0, 1.0),
- ("grass_height_m", "Grass height", " m", 0.001, 0.0, 1.0),
- ("compressibility_fraction", "Compressibility", " fraction", 0.01, 0.0, 1.0),
- (
- "compression_damping_fraction",
- "Compression damping",
- " fraction",
- 0.01,
- 0.0,
- 1.0,
- ),
- ("turf_density_kg_m3", "Turf density", " kg/m³", 1.0, 0.0, 10_000.0),
- ("moisture_fraction", "Moisture", " fraction", 0.01, 0.0, 1.0),
+from shared.python.swing_sim.ground.regional_plan_records import (
+ GroundRegionalMaterialPlanRequest,
)
-class MaterialEditor(QGroupBox):
- """Editable surface identity and full v1 material parameter collection."""
-
- def __init__(self, title: str, value: SurfaceMaterialDraft) -> None:
- super().__init__(title)
- self.surface_id = QLineEdit(value.surface_id)
- self.surface_id.setAccessibleName(f"{title} surface ID")
- self.surface_id.setToolTip(
- f"Stable identifier for {title.lower()}; included in validated readback."
- )
- self.fields: dict[str, QDoubleSpinBox] = {}
- layout = QFormLayout(self)
- layout.addRow("Surface ID", self.surface_id)
- for name, label, suffix, step, minimum, maximum in _MATERIAL_FIELDS:
- field = _number_input(
- f"{title} {label}",
- getattr(value, name),
- NumberInputSpec(suffix, step, minimum, maximum),
- )
- self.fields[name] = field
- layout.addRow(label, field)
-
- def draft(self) -> SurfaceMaterialDraft:
- """Read the current widgets without applying separate UI validation."""
- values = {name: field.value() for name, field in self.fields.items()}
- return SurfaceMaterialDraft(self.surface_id.text(), **values)
-
-
-class RegionalOverlayRow(QGroupBox):
- """One removable bounded regional overlay row."""
-
- def __init__(
- self,
- ordinal: int,
- value: RegionalOverlayDraft,
- remove: Callable[[RegionalOverlayRow], None],
- ) -> None:
- super().__init__(f"Regional overlay {ordinal}")
- self.region_id = QLineEdit(value.region_id)
- self.region_id.setToolTip(
- "Stable overlay identifier; it must be unique within the regional plan."
- )
- self.precedence = QSpinBox()
- self.precedence.setRange(0, 1_000_000)
- self.precedence.setValue(value.precedence)
- self.precedence.setToolTip(
- "Overlay selection precedence. Higher values win when intervals overlap."
- )
- self.lower_coordinate = _number_input(
- f"Overlay {ordinal} lower coordinate",
- value.lower_coordinate_m,
- NumberInputSpec(suffix=" m"),
- )
- self.upper_coordinate = _number_input(
- f"Overlay {ordinal} upper coordinate",
- value.upper_coordinate_m,
- NumberInputSpec(suffix=" m"),
- )
- self.material = MaterialEditor(f"Overlay {ordinal} material", value.surface)
- self.remove_button = QPushButton(f"Remove overlay {ordinal}")
- self.remove_button.setToolTip(
- "Remove this overlay from the unvalidated draft; one overlay is required."
- )
- self.remove_button.clicked.connect(lambda: remove(self))
- form = QFormLayout()
- form.addRow("Region ID", self.region_id)
- form.addRow("Precedence", self.precedence)
- form.addRow("Lower coordinate", self.lower_coordinate)
- form.addRow("Upper coordinate", self.upper_coordinate)
- layout = QVBoxLayout(self)
- layout.addLayout(form)
- layout.addWidget(self.material)
- layout.addWidget(self.remove_button, alignment=Qt.AlignmentFlag.AlignRight)
-
- def draft(self) -> RegionalOverlayDraft:
- """Read one overlay for authoritative contract validation."""
- return RegionalOverlayDraft(
- self.region_id.text(),
- self.precedence.value(),
- self.lower_coordinate.value(),
- self.upper_coordinate.value(),
- self.material.draft(),
- )
-
-
class RegionalSurfacePlanTab(QWidget):
"""Session-only regional surface editor with strict canonical readback."""
@@ -151,6 +46,8 @@ def __init__(self, parent: QWidget | None = None) -> None:
super().__init__(parent)
self._rows: list[RegionalOverlayRow] = []
self._initial = illustrative_regional_surface_plan_draft()
+ self._imported_request: GroundRegionalMaterialPlanRequest | None = None
+ self.file_actions = RegionalSurfacePlanFileActions(self, self)
self._build_ui()
self._connect_static_changes()
self._append_row(self._initial.regions[0])
@@ -173,7 +70,7 @@ def _connect_static_changes(self) -> None:
def _connect_row_changes(self, row: RegionalOverlayRow) -> None:
"""Connect one dynamic overlay to the shared invalidation boundary."""
row.region_id.textChanged.connect(self._mark_dirty)
- row.precedence.valueChanged.connect(self._mark_dirty)
+ row.precedence.textChanged.connect(self._mark_dirty)
row.lower_coordinate.valueChanged.connect(self._mark_dirty)
row.upper_coordinate.valueChanged.connect(self._mark_dirty)
self._connect_material_changes(row.material)
@@ -242,8 +139,8 @@ def _identity_box(self) -> QGroupBox:
)
geometry.setWordWrap(True)
session = QLabel(
- "Session-only draft: current workspace file commands do not persist "
- "model inputs."
+ "Open/Save As persists this canonical request only. Workspace "
+ "persistence remains a separate contract."
)
session.setWordWrap(True)
layout = QFormLayout(box)
@@ -257,15 +154,13 @@ def _identity_box(self) -> QGroupBox:
def _base_box(self) -> QGroupBox:
"""Create the base interval and complete base material editor."""
box = QGroupBox("Base surface and domain")
- self.domain_lower = _number_input(
+ self.domain_lower = coordinate_input(
"Base domain lower coordinate",
self._initial.lower_coordinate_m,
- NumberInputSpec(suffix=" m"),
)
- self.domain_upper = _number_input(
+ self.domain_upper = coordinate_input(
"Base domain upper coordinate",
self._initial.upper_coordinate_m,
- NumberInputSpec(suffix=" m"),
)
self.base_material = MaterialEditor("Base material", self._initial.base_surface)
layout = QVBoxLayout(box)
@@ -291,7 +186,21 @@ def _action_row(self) -> QHBoxLayout:
"Validate the complete draft and display its canonical SI request."
)
self.validate_button.clicked.connect(self.validate_plan)
+ self.open_button = QPushButton("Open JSON")
+ self.open_button.setAccessibleName("Open regional surface plan JSON")
+ self.open_button.setToolTip(
+ "Open and fully validate an editor-qualified canonical request."
+ )
+ self.open_button.clicked.connect(self.file_actions.open)
+ self.save_button = QPushButton("Save As JSON")
+ self.save_button.setAccessibleName("Save regional surface plan JSON as")
+ self.save_button.setToolTip(
+ "Atomically save the validated canonical request to a chosen file."
+ )
+ self.save_button.clicked.connect(self.file_actions.save_as)
layout.addWidget(self.add_button)
+ layout.addWidget(self.open_button)
+ layout.addWidget(self.save_button)
layout.addStretch(1)
layout.addWidget(self.validate_button)
return layout
@@ -362,10 +271,35 @@ def draft(self) -> RegionalSurfacePlanDraft:
tuple(row.draft() for row in self._rows),
)
+ def current_request(self) -> GroundRegionalMaterialPlanRequest:
+ """Return exact imported evidence unless the visible draft has changed."""
+ return regional_surface_plan_request_for_draft(
+ self.draft(), self._imported_request
+ )
+
+ def apply_imported_request(
+ self, request: GroundRegionalMaterialPlanRequest
+ ) -> None:
+ """Populate widgets only after complete strict editor qualification."""
+ draft = editor_draft_from_regional_surface_plan_request(request)
+ self.request_id.setText(draft.request_id)
+ self.source_revision.setText(draft.source_revision)
+ self.domain_lower.setValue(draft.lower_coordinate_m)
+ self.domain_upper.setValue(draft.upper_coordinate_m)
+ self.base_material.set_draft(draft.base_surface)
+ for row in self._rows:
+ self.rows_layout.removeWidget(row)
+ row.deleteLater()
+ self._rows.clear()
+ for region in draft.regions:
+ self._append_row(region)
+ self._update_row_actions()
+ self._imported_request = request
+
def validate_plan(self) -> None:
"""Validate through the strict contract and render canonical readback."""
try:
- request = validate_regional_surface_plan_draft(self.draft())
+ request = self.current_request()
except (TypeError, ValueError) as exc:
self.status_label.setText(str(exc))
self.status_label.setAccessibleName(
diff --git a/src/rate_of_closure/ui/pyqt6/regional_surface_plan_widgets.py b/src/rate_of_closure/ui/pyqt6/regional_surface_plan_widgets.py
new file mode 100644
index 000000000..33cbb0aab
--- /dev/null
+++ b/src/rate_of_closure/ui/pyqt6/regional_surface_plan_widgets.py
@@ -0,0 +1,231 @@
+"""Reusable PyQt6 inputs for the regional surface-plan editor."""
+
+from __future__ import annotations
+
+from collections.abc import Callable
+
+from PyQt6.QtCore import Qt
+from PyQt6.QtGui import QValidator
+from PyQt6.QtWidgets import (
+ QDoubleSpinBox,
+ QFormLayout,
+ QGroupBox,
+ QLineEdit,
+ QPushButton,
+ QVBoxLayout,
+)
+
+from rate_of_closure.application.regional_surface_plan import (
+ RegionalOverlayDraft,
+ SurfaceMaterialDraft,
+)
+from rate_of_closure.ui.pyqt6.engineering_number_input import (
+ NumberInputSpec,
+ engineering_number_input,
+)
+from shared.python.swing_sim.canonical_numeric_json import (
+ MAX_CANONICAL_SAFE_INTEGER,
+)
+
+_MAX_SAFE_FLOAT = float(MAX_CANONICAL_SAFE_INTEGER)
+_MAX_SAFE_INTEGER_TEXT = str(MAX_CANONICAL_SAFE_INTEGER)
+
+_MATERIAL_FIELDS = (
+ ("normal_restitution", "Normal restitution", "", 0.01, 0.0, 1.0),
+ ("static_friction", "Static friction", "", 0.01, 0.0, 5.0),
+ ("kinetic_friction", "Kinetic friction", "", 0.01, 0.0, 5.0),
+ ("rolling_resistance", "Rolling resistance", "", 0.01, 0.0, 1.0),
+ ("firmness_pa", "Firmness", " Pa", 1_000.0, 1e-11, _MAX_SAFE_FLOAT),
+ ("hardness_fraction", "Hardness", " fraction", 0.01, 0.0, 1.0),
+ ("grass_height_m", "Grass height", " m", 0.001, 0.0, _MAX_SAFE_FLOAT),
+ ("compressibility_fraction", "Compressibility", " fraction", 0.01, 0.0, 1.0),
+ (
+ "compression_damping_fraction",
+ "Compression damping",
+ " fraction",
+ 0.01,
+ 0.0,
+ 1.0,
+ ),
+ (
+ "turf_density_kg_m3",
+ "Turf density",
+ " kg/m³",
+ 1.0,
+ 0.0,
+ _MAX_SAFE_FLOAT,
+ ),
+ ("moisture_fraction", "Moisture", " fraction", 0.01, 0.0, 1.0),
+)
+
+
+def number_input(
+ name: str,
+ value: float,
+ spec: NumberInputSpec | None = None,
+) -> QDoubleSpinBox:
+ """Create one canonical-precision accessible SI number input."""
+ resolved_spec = spec or NumberInputSpec(
+ minimum=-_MAX_SAFE_FLOAT,
+ maximum=_MAX_SAFE_FLOAT,
+ decimals=11,
+ )
+ return engineering_number_input(name, value, resolved_spec)
+
+
+def coordinate_input(name: str, value: float) -> QDoubleSpinBox:
+ """Create one canonical-precision coordinate editor."""
+ return number_input(
+ name,
+ value,
+ NumberInputSpec(
+ suffix=" m",
+ minimum=-_MAX_SAFE_FLOAT,
+ maximum=_MAX_SAFE_FLOAT,
+ decimals=11,
+ ),
+ )
+
+
+class _SafeIntegerValidator(QValidator):
+ """Accept one decimal integer in the shared JSON-safe nonnegative range."""
+
+ def validate(
+ self, input_text: str | None, position: int
+ ) -> tuple[QValidator.State, str, int]:
+ input_text = input_text or ""
+ if input_text == "":
+ state = QValidator.State.Intermediate
+ elif not input_text.isascii() or not input_text.isdecimal():
+ state = QValidator.State.Invalid
+ elif len(input_text) < len(_MAX_SAFE_INTEGER_TEXT):
+ state = QValidator.State.Acceptable
+ elif input_text <= _MAX_SAFE_INTEGER_TEXT:
+ state = QValidator.State.Acceptable
+ else:
+ state = QValidator.State.Invalid
+ return state, input_text, position
+
+
+class SafeIntegerEdit(QLineEdit):
+ """Exact integer editor that does not narrow the v1 safe-integer contract."""
+
+ def __init__(self, name: str, value: int) -> None:
+ super().__init__()
+ self._name = name
+ self.setAccessibleName(name)
+ self.setMaxLength(len(_MAX_SAFE_INTEGER_TEXT))
+ self.setValidator(_SafeIntegerValidator(self))
+ self.set_value(value)
+
+ def set_value(self, value: int) -> None:
+ """Set one already validated exact safe integer without float conversion."""
+ if isinstance(value, bool) or not isinstance(value, int):
+ raise TypeError(f"{self._name} must be an integer")
+ if not 0 <= value <= MAX_CANONICAL_SAFE_INTEGER:
+ raise ValueError(f"{self._name} must lie within cross-runtime safe range")
+ self.setText(str(value))
+
+ def value(self) -> int:
+ """Return the exact integer or reject an incomplete editor value."""
+ if not self.hasAcceptableInput():
+ raise ValueError(f"{self._name} must lie within cross-runtime safe range")
+ return int(self.text())
+
+
+class MaterialEditor(QGroupBox):
+ """Editable surface identity and full v1 material parameter collection."""
+
+ def __init__(self, title: str, value: SurfaceMaterialDraft) -> None:
+ super().__init__(title)
+ self.surface_id = QLineEdit(value.surface_id)
+ self.surface_id.setAccessibleName(f"{title} surface ID")
+ self.surface_id.setToolTip(
+ f"Stable identifier for {title.lower()}; included in validated readback."
+ )
+ self.fields: dict[str, QDoubleSpinBox] = {}
+ layout = QFormLayout(self)
+ layout.addRow("Surface ID", self.surface_id)
+ for name, label, suffix, step, minimum, maximum in _MATERIAL_FIELDS:
+ field = number_input(
+ f"{title} {label}",
+ getattr(value, name),
+ NumberInputSpec(suffix, step, minimum, maximum, decimals=11),
+ )
+ self.fields[name] = field
+ layout.addRow(label, field)
+
+ def draft(self) -> SurfaceMaterialDraft:
+ """Read the current widgets without applying separate UI validation."""
+ values = {name: field.value() for name, field in self.fields.items()}
+ return SurfaceMaterialDraft(self.surface_id.text(), **values)
+
+ def set_draft(self, value: SurfaceMaterialDraft) -> None:
+ """Replace all visible material values from one validated draft."""
+ self.surface_id.setText(value.surface_id)
+ for name, field in self.fields.items():
+ field.setValue(getattr(value, name))
+
+
+class RegionalOverlayRow(QGroupBox):
+ """One removable bounded regional overlay row."""
+
+ def __init__(
+ self,
+ ordinal: int,
+ value: RegionalOverlayDraft,
+ remove: Callable[[RegionalOverlayRow], None],
+ ) -> None:
+ super().__init__(f"Regional overlay {ordinal}")
+ self.region_id = QLineEdit(value.region_id)
+ self.region_id.setToolTip(
+ "Stable overlay identifier; it must be unique within the regional plan."
+ )
+ self.precedence = SafeIntegerEdit(
+ f"Overlay {ordinal} precedence", value.precedence
+ )
+ self.precedence.setToolTip(
+ "Overlay selection precedence. Higher values win when intervals overlap."
+ )
+ self.lower_coordinate = coordinate_input(
+ f"Overlay {ordinal} lower coordinate",
+ value.lower_coordinate_m,
+ )
+ self.upper_coordinate = coordinate_input(
+ f"Overlay {ordinal} upper coordinate",
+ value.upper_coordinate_m,
+ )
+ self.material = MaterialEditor(f"Overlay {ordinal} material", value.surface)
+ self.remove_button = QPushButton(f"Remove overlay {ordinal}")
+ self.remove_button.setToolTip(
+ "Remove this overlay from the unvalidated draft; one overlay is required."
+ )
+ self.remove_button.clicked.connect(lambda: remove(self))
+ form = QFormLayout()
+ form.addRow("Region ID", self.region_id)
+ form.addRow("Precedence", self.precedence)
+ form.addRow("Lower coordinate", self.lower_coordinate)
+ form.addRow("Upper coordinate", self.upper_coordinate)
+ layout = QVBoxLayout(self)
+ layout.addLayout(form)
+ layout.addWidget(self.material)
+ layout.addWidget(self.remove_button, alignment=Qt.AlignmentFlag.AlignRight)
+
+ def draft(self) -> RegionalOverlayDraft:
+ """Read one overlay for authoritative contract validation."""
+ return RegionalOverlayDraft(
+ self.region_id.text(),
+ self.precedence.value(),
+ self.lower_coordinate.value(),
+ self.upper_coordinate.value(),
+ self.material.draft(),
+ )
+
+
+__all__ = [
+ "MaterialEditor",
+ "RegionalOverlayRow",
+ "SafeIntegerEdit",
+ "coordinate_input",
+ "number_input",
+]
diff --git a/src/rate_of_closure/variation/canonical_numeric_json.py b/src/rate_of_closure/variation/canonical_numeric_json.py
index b031cc6f8..a78b6a39e 100644
--- a/src/rate_of_closure/variation/canonical_numeric_json.py
+++ b/src/rate_of_closure/variation/canonical_numeric_json.py
@@ -1,5 +1,7 @@
-"""Compatibility import for the shared canonical numeric JSON encoder."""
+"""Capability-observation facade for canonical numeric JSON encoding."""
-from shared.python.swing_sim.canonical_numeric_json import canonical_numeric_json
+from shared.python.swing_sim.canonical_numeric_json import (
+ canonical_numeric_json_extended_floats as canonical_numeric_json,
+)
__all__ = ["canonical_numeric_json"]
diff --git a/src/rate_of_closure/web/src/components/RegionalSurfacePlanPanel.test.tsx b/src/rate_of_closure/web/src/components/RegionalSurfacePlanPanel.test.tsx
index 1356cb121..72d77dc51 100644
--- a/src/rate_of_closure/web/src/components/RegionalSurfacePlanPanel.test.tsx
+++ b/src/rate_of_closure/web/src/components/RegionalSurfacePlanPanel.test.tsx
@@ -1,13 +1,22 @@
-import { fireEvent, render, screen } from "@testing-library/react";
-import { describe, expect, it } from "vitest";
+import { fireEvent, render, screen, waitFor } from "@testing-library/react";
+import { afterEach, describe, expect, it, vi } from "vitest";
import {
MAX_REGIONAL_SURFACE_EDITOR_ROWS,
buildGroundRegionalSurfacePlanRequest,
+ editorDraftFromGroundRegionalSurfacePlanRequest,
illustrativeRegionalSurfacePlanDraft,
+ regionalSurfacePlanRequestForDraft,
} from "../model/regionalSurfacePlan";
+import {
+ MAX_GROUND_REGIONAL_PLAN_WIRE_BYTES,
+ parseGroundRegionalMaterialPlanRequest,
+ stableGroundRegionalMaterialPlanJson,
+} from "../model/groundRegionalPlan";
import { RegionalSurfacePlanPanel } from "./RegionalSurfacePlanPanel";
+afterEach(() => vi.restoreAllMocks());
+
describe("RegionalSurfacePlanPanel", () => {
it("matches Python provenance for the disclosed illustrative draft", () => {
const request = buildGroundRegionalSurfacePlanRequest(
@@ -49,6 +58,32 @@ describe("RegionalSurfacePlanPanel", () => {
.not.toBeInTheDocument();
});
+ it("accepts the exact cross-runtime maximum precedence", () => {
+ render();
+ fireEvent.change(screen.getByLabelText("Overlay 1 precedence"), {
+ target: { value: String(Number.MAX_SAFE_INTEGER) },
+ });
+
+ fireEvent.click(screen.getByRole("button", { name: "Validate surface plan" }));
+
+ expect(screen.queryByRole("alert")).not.toBeInTheDocument();
+ expect(screen.getByRole("status", { name: "Regional surface plan readback" }))
+ .toHaveTextContent("1 overlay(s)");
+ });
+
+ it("rejects integer-valued material numbers beyond the cross-runtime safe range", () => {
+ render();
+ fireEvent.change(screen.getByLabelText("Base Firmness (Pa)"), {
+ target: { value: "10000000000000000" },
+ });
+
+ fireEvent.click(screen.getByRole("button", { name: "Validate surface plan" }));
+
+ expect(screen.getByRole("alert")).toHaveTextContent(/cross-runtime safe range/i);
+ expect(screen.queryByRole("status", { name: "Regional surface plan readback" }))
+ .not.toBeInTheDocument();
+ });
+
it("links invalid interval fields to an accessible error without clearing input", () => {
render();
const lower = screen.getByLabelText("Overlay 1 lower coordinate (m)");
@@ -84,6 +119,123 @@ describe("RegionalSurfacePlanPanel", () => {
.toHaveLength(MAX_REGIONAL_SURFACE_EDITOR_ROWS);
expect(add).toBeDisabled();
expect(screen.queryByRole("button", { name: /run|play/i })).not.toBeInTheDocument();
- expect(screen.getByText(/session-only draft/i)).toBeInTheDocument();
+ expect(screen.getByText(/workspace persistence remains separate/i)).toBeInTheDocument();
+ });
+
+ it("preserves an unchanged imported editor request exactly", () => {
+ const request = buildGroundRegionalSurfacePlanRequest({
+ ...illustrativeRegionalSurfacePlanDraft(), request_id: "imported-plan",
+ });
+
+ const imported = editorDraftFromGroundRegionalSurfacePlanRequest(request);
+
+ expect(regionalSurfacePlanRequestForDraft(imported, request)).toBe(request);
+ expect(stableGroundRegionalMaterialPlanJson(
+ regionalSurfacePlanRequestForDraft(imported, request),
+ )).toBe(stableGroundRegionalMaterialPlanJson(request));
+
+ const payload = JSON.parse(stableGroundRegionalMaterialPlanJson(request));
+ payload.provenance.input_sha256 = "0".repeat(64);
+ const mismatched = parseGroundRegionalMaterialPlanRequest(payload);
+ expect(() => editorDraftFromGroundRegionalSurfacePlanRequest(mismatched))
+ .toThrow(/digest does not match/i);
+ });
+
+ it("imports only after complete validation and retains the prior draft on error", async () => {
+ render();
+ const request = buildGroundRegionalSurfacePlanRequest({
+ ...illustrativeRegionalSurfacePlanDraft(), request_id: "browser-opened-plan",
+ });
+ const input = screen.getByLabelText("Import regional surface plan JSON file");
+ const validText = stableGroundRegionalMaterialPlanJson(request);
+ const valid = {
+ name: "valid.json",
+ size: new TextEncoder().encode(validText).byteLength,
+ text: vi.fn().mockResolvedValue(validText),
+ };
+
+ fireEvent.change(input, { target: { files: [valid] } });
+ await waitFor(() => expect(screen.getByLabelText("Regional plan request ID"))
+ .toHaveValue("browser-opened-plan"));
+
+ const corrupt = {
+ name: "corrupt.json", size: 47,
+ text: vi.fn().mockResolvedValue('{"request_id":"one","request_id":"two"}'),
+ };
+ fireEvent.change(input, { target: { files: [corrupt] } });
+ await waitFor(() => expect(screen.getByRole("alert")).toHaveTextContent(/duplicate/i));
+ expect(screen.getByLabelText("Regional plan request ID"))
+ .toHaveValue("browser-opened-plan");
+
+ const invalidSyntax = {
+ name: "syntax.json", size: 9,
+ text: vi.fn().mockResolvedValue("{not-json"),
+ };
+ fireEvent.change(input, { target: { files: [invalidSyntax] } });
+ await waitFor(() => expect(screen.getByRole("alert")).toHaveTextContent(/invalid profile json/i));
+ expect(screen.getByLabelText("Regional plan request ID"))
+ .toHaveValue("browser-opened-plan");
+ });
+
+ it("rejects non-editor qualification without populating the editor", async () => {
+ render();
+ const request = buildGroundRegionalSurfacePlanRequest(
+ illustrativeRegionalSurfacePlanDraft(),
+ );
+ const payload = JSON.parse(stableGroundRegionalMaterialPlanJson(request));
+ payload.provenance.producer = "external.course.authority";
+ const input = screen.getByLabelText("Import regional surface plan JSON file");
+ const file = {
+ name: "external.json", size: 100,
+ text: vi.fn().mockResolvedValue(JSON.stringify(payload)),
+ };
+
+ fireEvent.change(input, { target: { files: [file] } });
+
+ await waitFor(() => expect(screen.getByRole("alert")).toHaveTextContent(/editor producer/i));
+ expect(screen.getByLabelText("Regional plan request ID"))
+ .toHaveValue("illustrative-regional-plan");
+ });
+
+ it("rejects oversized browser files before allocating their text", async () => {
+ render();
+ const input = screen.getByLabelText("Import regional surface plan JSON file");
+ const text = vi.fn().mockResolvedValue("{}");
+ const file = {
+ name: "oversize.json", size: MAX_GROUND_REGIONAL_PLAN_WIRE_BYTES + 1, text,
+ };
+
+ fireEvent.change(input, { target: { files: [file] } });
+
+ await waitFor(() => expect(screen.getByRole("alert")).toHaveTextContent(/maximum wire size/i));
+ expect(text).not.toHaveBeenCalled();
+ expect(screen.getByLabelText("Regional plan request ID"))
+ .toHaveValue("illustrative-regional-plan");
+ });
+
+ it("downloads canonical bytes and revokes its object URL", () => {
+ const createUrl = vi.fn(() => "blob:regional-plan");
+ const revokeUrl = vi.fn();
+ Object.defineProperty(URL, "createObjectURL", { configurable: true, value: createUrl });
+ Object.defineProperty(URL, "revokeObjectURL", { configurable: true, value: revokeUrl });
+ const click = vi.spyOn(HTMLAnchorElement.prototype, "click").mockImplementation(() => {});
+ render();
+
+ fireEvent.click(screen.getByRole("button", { name: "Download regional surface plan JSON" }));
+
+ expect(createUrl).toHaveBeenCalledOnce();
+ expect(click).toHaveBeenCalledOnce();
+ expect(revokeUrl).toHaveBeenCalledWith("blob:regional-plan");
+ });
+
+ it("treats an empty browser chooser as cancellation", () => {
+ render();
+ const input = screen.getByLabelText("Import regional surface plan JSON file");
+
+ fireEvent.change(input, { target: { files: [] } });
+
+ expect(screen.queryByRole("alert")).not.toBeInTheDocument();
+ expect(screen.getByLabelText("Regional plan request ID"))
+ .toHaveValue("illustrative-regional-plan");
});
});
diff --git a/src/rate_of_closure/web/src/components/RegionalSurfacePlanPanel.tsx b/src/rate_of_closure/web/src/components/RegionalSurfacePlanPanel.tsx
index 068fff039..6e8fc544c 100644
--- a/src/rate_of_closure/web/src/components/RegionalSurfacePlanPanel.tsx
+++ b/src/rate_of_closure/web/src/components/RegionalSurfacePlanPanel.tsx
@@ -1,13 +1,19 @@
-import { useState } from "react";
+import { type ChangeEvent, useRef, useState } from "react";
import {
MAX_REGIONAL_SURFACE_EDITOR_ROWS,
- buildGroundRegionalSurfacePlanRequest,
+ editorDraftFromGroundRegionalSurfacePlanRequest,
illustrativeRegionalSurfacePlanDraft,
+ regionalSurfacePlanRequestForDraft,
type RegionalOverlayDraft,
type RegionalSurfacePlanDraft,
type SurfaceMaterialDraft,
} from "../model/regionalSurfacePlan";
+import {
+ downloadRegionalSurfacePlanRequest,
+ readRegionalSurfacePlanFile,
+} from "../model/regionalSurfacePlanFiles";
+import type { GroundRegionalMaterialPlanRequest } from "../model/groundRegionalPlan";
type NumericMaterialKey = Exclude;
@@ -133,15 +139,20 @@ function nextOverlay(draft: RegionalSurfacePlanDraft): RegionalOverlayDraft {
export function RegionalSurfacePlanPanel() {
const [draft, setDraft] = useState(illustrativeRegionalSurfacePlanDraft);
+ const [importedRequest, setImportedRequest] =
+ useState(null);
const [error, setError] = useState(null);
const [readback, setReadback] = useState(null);
+ const [fileStatus, setFileStatus] = useState(null);
const [validationAttempted, setValidationAttempted] = useState(false);
+ const fileInput = useRef(null);
const updateDraft = (
transform: (current: RegionalSurfacePlanDraft) => RegionalSurfacePlanDraft,
) => {
setDraft(transform);
setError(null);
setReadback(null);
+ setFileStatus(null);
setValidationAttempted(false);
};
const updateRegion = (index: number, value: RegionalOverlayDraft) =>
@@ -152,7 +163,7 @@ export function RegionalSurfacePlanPanel() {
const validate = () => {
setValidationAttempted(true);
try {
- const request = buildGroundRegionalSurfacePlanRequest(draft);
+ const request = regionalSurfacePlanRequestForDraft(draft, importedRequest);
setError(null);
setReadback(
`${request.schema_version} · ${request.unit_system} · ` +
@@ -165,6 +176,35 @@ export function RegionalSurfacePlanPanel() {
setError(caught instanceof Error ? caught.message : "Surface plan is invalid");
}
};
+ const importFile = async (event: ChangeEvent) => {
+ const file = event.currentTarget.files?.[0];
+ event.currentTarget.value = "";
+ if (file === undefined) return;
+ try {
+ const request = await readRegionalSurfacePlanFile(file);
+ const importedDraft = editorDraftFromGroundRegionalSurfacePlanRequest(request);
+ setDraft(importedDraft);
+ setImportedRequest(request);
+ setValidationAttempted(false);
+ setError(null);
+ setReadback(`${request.schema_version} · exact imported provenance ${request.provenance.input_sha256}`);
+ setFileStatus(`Imported ${file.name}. No physics executed.`);
+ } catch (caught) {
+ setError(caught instanceof Error ? caught.message : "Regional plan import failed");
+ setFileStatus("Import failed; the editor and prior validated readback were preserved.");
+ }
+ };
+ const download = () => {
+ try {
+ const request = regionalSurfacePlanRequestForDraft(draft, importedRequest);
+ downloadRegionalSurfacePlanRequest(request);
+ setError(null);
+ setFileStatus("Download prepared. Your browser controls the destination and overwrite behavior.");
+ } catch (caught) {
+ setError(caught instanceof Error ? caught.message : "Regional plan download failed");
+ setFileStatus("Download failed; no browser filesystem state was changed.");
+ }
+ };
return (
@@ -181,7 +221,8 @@ export function RegionalSurfacePlanPanel() {
This slice validates a material plan only; it does not run physics or playback.
- Session-only draft: the current web workspace adapter does not persist model inputs.
+ Import/download persists this canonical request only; workspace persistence remains separate.
+ Browser downloads cannot promise a native path, atomic replacement, or recent-file access.