CONS-RATE: Complete #4142/#4433 visualization authority - #4473
Conversation
Rebuild the approved Rate/swing/golf campaign directly on current main, excluding inherited non-Rate formatter churn and scratch-worktree gitlinks. Reconcile cumulative visual package-data assertions and hosted typing boundaries without changing scientific behavior.
Narrow NumPy, Qt, mapping, and constructor boundaries across the consolidated Rate/swing authority so the exact Python 3.12/MyPy 1.13 changed-source command passes without runtime or scientific changes. Correct the evidence count and advance the canonical handoffs/SPEC.
…33-consolidated-release
…33-consolidated-release # Conflicts: # tests/ops/test_cross_repo_python_integration.py
…33-consolidated-release # Conflicts: # SPEC.md
Collision warning: two consolidations of the same campaign, both armed to auto-merge#4447 (
Neither branch subsumes the other, so merging one and closing the other loses work in both directions. This is the same trap measured earlier in this drive, where 26 of 53 non-tip PRs held commits absent from every descendant tip — a later, larger consolidation is not automatically a superset. What each side uniquely holds#4473's 98 unique files are pure additions — absent from #4447's 73 unique files include work that #4473 states it deliberately excluded. #4473's description says it "excludes inherited unrelated repository-wide formatter churn, Movement Optimizer/pendulum/Sidekick work". That exclusion is not only churn — the excluded set contains substantive changes:
The 168 divergent files are the real problem802 shared files are byte-identical, so the two branches largely agree. The 168 that differ (125 under RecommendationPick one branch as the vehicle and port the other's unique content into it, rather than merging both:
No action has been taken on either branch. #4447 is deliberately being held unpushed so it cannot land and strand #4473's additions. |
…33-consolidated-release
`tests` already declared `needs: [pick-runner]` but ignored the dispatcher's `runner` output and hardcoded `runs-on: d-sorg-fleet`. It was the only lane that did not honour CI_RUNNER_MODE, and it is the one that gates merges: `tests (3.11)` is a required check. The effect was that every merge queued behind a self-hosted pool that routinely sits at zero idle runners while fully online — the exact condition the `pick-runner` comment already documents. Measured at the time of this change: 5 online `d-sorg-fleet` runners, all busy, 0 idle, against 100 queued workflow runs and 1 in progress. PRs were BLOCKED on queue depth, not on any test result. `CI_RUNNER_MODE` is already set to `hosted` on this public repo, so free unmetered hosted capacity was available the whole time. Consuming `needs.pick-runner.outputs.runner` uses the machinery that was built for this and was otherwise dead. Routing is unchanged everywhere else: `local` still pins the fleet, private repos still fall through to it, and a private repo with no idle capacity still fails closed. `PIP_CACHE_DIR` pointed at a fleet-host path that a hosted runner cannot create (different user, no write access above $HOME), which would have aborted pip before it installed anything. It now falls back to a workspace-local cache when the job is not on the fleet. `fix-brick-toolcache` and `rust-quality-gate` keep their explicit `d-sorg-fleet` targets — neither is a required check. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
With the required lane finally executing (previous commit), `tests (3.11)` reported 4392 passed / 11 failed. None of these were visible before: the job had been sitting in the self-hosted queue rather than running. pandas 3.0 removed `DataFrame.applymap` (7 failures). `_validate_request` already preferred `.map` and kept `applymap` as a fallback, but bound the fallback eagerly — so merely *resolving* `projected.applymap` raised AttributeError on 3.x before the modern path was ever reached. Resolved lazily, and the unreachable-both case now says so instead of raising a bare attribute error. pandas 3.0 also infers `StringDtype(na_value=nan)` for a text column, which turned the `None` that `_coerce_csv_cell` deliberately returns for a blank field into `nan` and broke the contract that a blank CSV field reads back as `null`, matching the browser (1 failure). The CSV frame is now built with `dtype=object`: every cell's type was already decided by `_coerce_csv_cell`, so re-inference was never wanted. This restores the pre-pandas-3 behaviour exactly. The JSON path's handling of absent keys is untouched — it is a separate pre-existing question, not a regression. The Python/TypeScript wind parity fixture asserted 1e-12 (1 failure). That is not reproducible across runtimes: `_unit_noise` uses the `fract(sin(x) * 43758.5453)` hash, so a 1-ulp `math.sin` difference between glibc and MSVC/V8 lands ~4e-12 out in the phase. The test passed on Windows and failed on Linux for that reason alone. Both sides now state 1e-9, which is eleven orders below any meaningful wind speed, so the parity contract keeps its content. The instability itself can diverge by O(1) near a `% 1.0` boundary and is tracked in #4513 — this commit does not paper over that, it files it. The Morris authority child failure (1) reported "invalid readiness" when the child had in fact died before printing a port: `readline` returns `""` at EOF and the empty string fell through to the malformed-line branch, while `stderr=DEVNULL` discarded the reason. EOF is now distinguished from a malformed announcement, and stderr is captured to a temporary file — a file rather than a PIPE, since nothing drains the child's stderr while the parent blocks on stdout. This does not itself fix the child; it makes the next failure say why. Verified locally on pandas 3.0.3 / CPython 3.13: 2218 passed across `tests/rate_of_closure` and `src/shared/python/swing_sim`. The one remaining local failure, `test_variation_ensemble_io_reader.py::test_text_reader_ normalizes_decoder_resource_errors`, reproduces with these changes stashed and passed on Linux CI — pre-existing and Windows-specific, untouched here. Scoped ruff check, ruff format and mypy are clean; the two pandas modules crash mypy 1.13 identically with and without this change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…the child
The last remaining CI failure, now that the error reports its own cause:
Morris authority child closed stdout before announcing a port:
child exited with 1; stderr: ModuleNotFoundError: No module named 'uvicorn'
uvicorn *is* installed — the tests job installs it, and the log shows
`Successfully installed ... uvicorn-0.52.3` into `$RUNNER_TEMP/ci-venv`, which
is the venv pytest itself runs in. The child could not see it because
`_spawn_child` called `Path(sys.executable).resolve()`.
On POSIX a virtualenv's `bin/python` is a symlink to the base interpreter, so
resolving it hands the child the base interpreter and silently discards the
venv's site-packages. Verified directly on this machine's Ubuntu-22.04:
venv python : /tmp/tmpoub08vl5/bin/python
resolved : /usr/bin/python3.10
Windows venvs copy the executable rather than symlinking it, which is why the
integration test passed locally and only ever failed on Linux CI. `.resolve()`
bought nothing here — `sys.executable` is already absolute — so it is dropped
and the absoluteness it implied is asserted explicitly instead.
Added a regression test that builds a symlinked venv layout, captures the
spawned argv, and asserts it is `sys.executable` verbatim rather than the
symlink target. It skips where symlinks need privilege (Windows) and runs on
Linux, which is where the failure lives — confirmed under WSL.
Local: 7 passed, 1 skipped. Scoped ruff, ruff format and mypy clean.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ate (#4514) Both documents had drifted far enough to actively misdirect the next agent, and the root document had also outgrown its own policy by 18x. CLAUDE.md requires handoff docs to be current-state only and at most 150 lines, with history in git. The root doc had instead accumulated 137 dated entries across 2,708 lines. Those entries are moved verbatim to docs/agent_handoff_archive/2026-08_tools_root_handoff_log.md, not deleted — the archived body is byte-identical to the original (165,356 chars, 137 entries), so no working-tree context is lost. The live doc is now 132 lines and carries an explicit do-not against appending dated entries again. Content corrections. The root doc presented PR #4119 as open with auto-merge armed and #4124/#4129 as open drafts stacked on it; in fact #4119 closed without merging and #4124/#4129 both merged. Epics #4142 and #4433 were absent entirely. Delivery has shifted from stacked PRs to scoped consolidations rebuilt onto current main. It now records the seven live epics, the four open consolidations (#4446, #4447, #4449, #4466) as the real queue, and the fact that 39 of 58 open PRs are codex/4142-* / codex/4433-* drafts superseded by merged #4473 — whose own description says so. Those should be triaged and closed, not rebased. The pendulum doc described issue #4406 as active on branch research/shoulder-velocity-drift-transfer. #4406 is closed and shipped via consolidation #4450. It now records what landed, keeps the fail-closed triple/golfer tier boundary as an explicit do-not, and points at the UpstreamDrift #8684 qualification state — including the finite-ground result where the preregistered screen admitted 0 of 384 cells, so a moving base is not a free upgrade for the higher tiers. Also recorded: the four pre-existing ruff format failures under src/data_processing/ that are on main and should not be absorbed into an unrelated PR, and the --regenerate-api-baseline trap. Co-authored-by: codex-scheduled <codex-scheduled@users.noreply.github.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Outcome
Consolidates the approved #4142/#4433 Rate of Closure visualization and scientific-authority campaign directly onto current
main(73fd3d49039a5d203c88252cede42085a7724cbe). This is a clean scoped rebuild: it excludes inherited unrelated repository-wide formatter churn, Movement Optimizer/pendulum/Sidekick work, and six scratch-worktree gitlinks while preserving current-main CI/PDF-renamer authority.Included authority
Clean consolidation reconciliation
Local evidence on exact commit
14d0167304b76b83d6c6ab9d40f66c0382b42aebswing-core12,tools-core111).git diff --check: green.Evidence and remaining limits
The 18 strict visual references remain proposed until this protected consolidation merges. Responsive React and PyQt DPI 1.5 captures are diagnostic rather than approved reference baselines. Manual assistive-technology qualification, portable cross-runtime raw solver/mesh/archive replay, and cross-platform pixel identity remain open and are not claimed complete.
After protected merge, this PR supersedes only the remaining #4142/#4433 draft chain. It does not modify or supersede #4438; that PR's existing squash auto-merge remains untouched.