Skip to content

CONS-A4: completist docs audit + pendulum drift-transfer diagnostics (supersedes #4080, #4411) - #4450

Merged
dieterolson merged 15 commits into
mainfrom
consolidated/docs-pendulum-2026-08-13
Aug 15, 2026
Merged

CONS-A4: completist docs audit + pendulum drift-transfer diagnostics (supersedes #4080, #4411)#4450
dieterolson merged 15 commits into
mainfrom
consolidated/docs-pendulum-2026-08-13

Conversation

@dieterolson

@dieterolson dieterolson commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

CONS-A4. Consolidates the two remaining unrelated-subsystem PRs into one merge boundary.

Supersedes #4080 (jules-...-8eacfe8f, completist docs audit) and #4411
(research/shoulder-velocity-drift-transfer, pendulum drift-transfer diagnostics).

Containment verified by ancestry, not by title: verify_coverage.sh reports
covered=2 NOT-covered=0 against this branch, so closing both drops nothing.

Why these two are one PR

They are unrelated subsystems, so the honest answer to "one PR or two" is decided
by whether they interfere: they do not. #4411 merged into #4080 with zero
conflicts, and after de-churning (below) their file sets are disjoint. Kept as one
PR because every extra PR costs ~28 workflow runs and ~4 self-hosted fleet slots,
which is the problem this whole drive exists to fix. The two halves are cleanly
separable for review:

Half Files What to review
Completist docs (#4080) 19 Regenerated completist scan data, one new dated report, 6 new issue docs, 4 renames, COMPLETIST_LATEST.md refresh, plus two genuine CI fleet-load fixes
Pendulum diagnostics (#4411) 10 transfer_strategy.py + transfer_strategy_panel.py + 2 test modules + docs. This is the substantive code change

29 files, +1989/-220.

The two CI fixes are worth their own attention

#4080's branch carried two changes that have nothing to do with completist docs
and are the most immediately valuable thing in this PR — cheap if: pre-filters
hoisted onto the pick-runner jobs of Jules-Issue-Mention-Handler.yml and
PR-Comment-Responder.yml. GitHub evaluates them before scheduling, so a
non-matching comment now costs zero fleet capacity instead of occupying two
d-sorg-fleet runners just to be skipped one job later.

Defects found and fixed while consolidating

  1. docs(completist): audit completist data and generate report #4080 deleted 90 documentation files. Reverted. The branch removed 19
    dated historical Completist_Report_*.md (2026-03-08 … 2026-07-23), 7
    hand-written docs/assessments/issues/ISSUE_*.md (security data leakage, test
    coverage, logging split, constants duplication, two thesis-defence reviews,
    duplicate file IO), and 57 generated Issue_NNNN_*.md. It also deleted
    docs/development/professional-scada-epic.md.

    This is an agent regression, not tool behaviour and not a retention policy:

    • The PR body describes only "collected markers / parsed codebase / generated
      issues / generated report". No deletion is mentioned.
    • The generator does not delete. scripts/analyze_completist_data.py contains
      no unlink, rmtree, or remove; it only globs ISSUES_DIR to deduplicate
      and count.
    • 19 months of dated reports were being kept on main, and the new report's own
      trend visualisation depends on that history.
    • The regenerated issue set restarts numbering at Issue_005 instead of
      continuing from Issue_2027, so it is not a superset of what it removed.

    All 90 restored from main. Deliberate pruning, if wanted, belongs in its own
    reviewable PR.

  2. Stale-base revert in .jules/bolt.md. docs(completist): audit completist data and generate report #4080's side removed the two Bolt
    learnings main gained from ⚡ Bolt: Optimize SVG path string allocations #4071 and ⚡ Bolt: Replace map and reduce array methods with single-pass loops in default tab initializers #4176 after the branch forked. Kept
    main's content.

  3. Committed gitlinks. Six 160000 entries under .codex-worktrees/,
    inherited by docs(completist): audit completist data and generate report #4080. origin/main has none, no .gitmodules declares them, and
    the commits they reference exist on no remote — a fresh clone would get six
    dangling gitlinks. Removed. (.gitignore deliberately untouched; that line is
    owned by CONS-A1 CONS-A1: CI/infra consolidation (file-size-budget checkout, pdf_renamer SQLite leak, fleet-load fixes) #4445.)

  4. ~290 files of inherited formatting churn reverted. docs(completist): audit completist data and generate report #4080's branch carried
    three repo-wide pre-commit commits (ba3730ac1, 35bec2d99, c70755ba1)
    produced by a ruff build that disagrees with the CI-pinned 0.14.10 — 281 of
    299
    changed .py files failed ruff format --check under the pinned
    version, the same red-gate mode that blocked 🎨 Palette & Bolt Suite: Form Submission, Accessibility, SVG & CSV Optimizations #4429/Codex Flight Suite: Consolidated Agent Flight and Metric Models #4437/Codex Rate of Closure Suite: Consolidated Agent Camera, Attribution and Execution Workflows #4439. The churn also
    displaced # noqa comments, producing 9 live F841 errors in
    tests/unit/sidekick/test_sidekick_ux_hardening.py, a UP017 rewrite in
    test_action_audit.py, and two lost SLF001 suppressions in
    test_sidekick_f4_collaborators.py. It further reformatted
    src/pendulum_simulator/, src/movement_optimizer/ and
    src/data_processing/, which the CI format gate excludes and repo policy says
    not to touch.

    280 of the 295 modified .py files were proven content-neutral before
    reverting: each file's blob and main's blob normalise to identical bytes under
    one identical ruff 0.14.10 format pass. The remaining 15 were reverted on
    provenance — none is owned by a docs-only task or a pendulum-only change — and
    each was inspected to be reflow plus displaced-noqa only. Pendulum: Add Drift-Transfer Diagnostics #4411's own files
    were taken from its head, which forked from current main and is churn-free.

    Net: 299 changed .py files → 5; 323 files → 29. This also removes the
    pendulum churn STATE.md predicted would collide with CONS-B1: Palette & Bolt Suite (form submission, accessibility, SVG & CSV optimizations) + movement-optimizer motion-view extraction #4438.

Verification

  • ruff check / ruff format --check (pinned 0.14.10), replicating
    ci-standard.yml's exact grep -v exclude list: 0 files gated — the only
    changed .py files are Pendulum: Add Drift-Transfer Diagnostics #4411's 5, all under the excluded
    src/pendulum_simulator/ tree. Checked them anyway: lint clean, all 5 already
    formatted.
  • double_pendulum_golf.transfer_strategy imports cleanly and exposes
    TransferSignals, TransferSummary, double_pendulum_transfer_signals,
    pareto_front, summarize_transfer.
  • git grep "<<<<<<< HEAD" empty; no bare from datetime import UTC; zero
    mode-160000 entries.
  • Pendulum: Add Drift-Transfer Diagnostics #4411's pytest run could not be completed locally: pytest-qt aborts at
    configure time with ImportError: DLL load failed while importing QtCore. That
    is the known PyQt6 6.10 / Qt6Core.dll fault on this machine, an environment
    problem rather than a PR defect. CI runs the suite.

Issue references

Closes #4406 — carried over from #4411, which delivers the model-neutral
transfer-signal contract, the exact drift/control grip-force closure checks, the
phase-window work/braking/impulse metrics, the Pareto ranking, and the PyQt
Drift Transfer tab that fails closed for unqualified model tiers. SPEC.md
§12 carries its dated Change Log row.

Supports D-sorganization/UpstreamDrift#8551.

#4080 references no issue — it is a bot-generated documentation audit.

Reviewer note

quality-gate is the fast hosted gate. tests (3.11) runs on the 7-runner
self-hosted fleet behind a pick-runner job; a tests (3.11) check that has not
been created yet means pick-runner is still queued — that is a queue, not a
failure.

google-labs-jules Bot and others added 11 commits August 2, 2026 10:46
Co-authored-by: dieterolson <198168927+dieterolson@users.noreply.github.com>
Co-authored-by: dieterolson <198168927+dieterolson@users.noreply.github.com>
…nsolidated/docs-pendulum-2026-08-13

Carries the additive completist output and reverts the branch's destructive
deletions.

Conflict: .jules/bolt.md — #4080's side removed the two Bolt learnings that
main gained from #4071 and #4176 after this branch forked. Kept main's content;
the removal was a stale-base artifact, not an intended edit.

Reverted 90 file deletions the branch carried:
  - 19 dated historical Completist_Report_*.md (2026-03-08 .. 2026-07-23)
  - 7 hand-written docs/assessments/issues/ISSUE_*.md (security data leakage,
    test coverage, logging split, constants duplication, two thesis-defence
    reviews, duplicate file IO)
  - 57 generated Issue_NNNN_*.md
The PR body claims only "collected markers / parsed codebase / generated issues
/ generated report" — no deletion is described. The generator itself does not
delete: scripts/analyze_completist_data.py has no unlink/rmtree/remove and only
globs ISSUES_DIR to deduplicate and count. So the deletions came from the agent,
not the tool, and not from any retention policy — 19 months of dated reports
were being kept on main, and the new report's own trend visualisation depends on
that history. The regenerated issue set also restarts numbering at Issue_005
rather than continuing from Issue_2027, so it is not a superset of what it
removed. Restored all 90 from main; pruning, if wanted, belongs in a deliberate
PR.

Kept from the branch: 5 .jules/completist_data/*.txt scan outputs, the new
Completist_Report_2026-08-02.md, 12 new Issue_0NN_*.md, the COMPLETIST_LATEST.md
refresh, and two genuine fleet-load fixes hoisting cheap `if:` pre-filters onto
the pick-runner jobs of Jules-Issue-Mention-Handler.yml and
PR-Comment-Responder.yml so a non-matching comment stops occupying two
d-sorg-fleet runners.
…-transfer' into consolidated/docs-pendulum-2026-08-13
Six git-mode-160000 entries under .codex-worktrees/ (Codex agent scratch
worktrees committed by accident), inherited by #4080 from a shared ancestor.
origin/main has zero of them, no .gitmodules declares them, and the commits they
point at exist only in one local clone and are on no remote branch — so a fresh
clone after this merged would carry six gitlinks referencing objects the server
does not have.

.gitignore is deliberately not edited here — the .codex-worktrees/ ignore rule
is owned by CONS-A1 (#4445) so it lands as a single change.
#4080's branch carried three repo-wide pre-commit commits (ba3730a "style:
apply automated pre-commit formatting", 35bec2d "fix: pre-commit checks and
main sync", c70755b "style/fix: pre-commit automated fixes") touching ~300
files that neither the completist docs task nor the pendulum work has anything to
do with. That churn is not benign:

* It was produced by a ruff build that disagrees with the CI-pinned ruff 0.14.10,
  so 281 of the 299 changed .py files FAILED `ruff format --check` under the
  pinned version — the same red-gate mode that blocked #4429/#4437/#4439.
* Its line-wrapping displaced trailing `# noqa` comments onto closing-paren
  lines where they no longer suppress anything, producing 9 real F841 errors in
  tests/unit/sidekick/test_sidekick_ux_hardening.py, a UP017 in
  tests/unit/sidekick/agent/test_action_audit.py, and losing two SLF001
  suppressions in test_sidekick_f4_collaborators.py.
* It reformatted src/pendulum_simulator/, src/movement_optimizer/ and
  src/data_processing/ — trees the CI format gate explicitly excludes
  (ci-standard.yml) and repo policy says not to reformat.

Reverted by path to origin/main, keeping only what the two PRs own:
.jules/**, docs/assessments/**, the two workflow pre-filters, SPEC.md,
AGENT_HANDOFF.md, and #4411's 10 files (taken from its own head, which forked
from current main and so is churn-free).

280 of the 295 modified .py files were proven content-neutral first: HEAD's blob
and main's blob normalise to identical bytes under one identical ruff 0.14.10
format pass, so reverting them drops nothing. The remaining 15 were reverted on
provenance instead — none is owned by #4080 (a docs-only task) or #4411 (pendulum
only) — and each was inspected to be reflow plus displaced-noqa only.

Net effect: 299 changed .py files -> 5, and the diff drops from 323 files to 29.
This also removes the pendulum/movement-optimizer churn that STATE.md predicted
would collide with #4438.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9b5791ae5d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +180 to +182
total_work = float(np.trapezoid(total_power, time))
drift_work = float(np.trapezoid(drift_power, time))
control_work = float(np.trapezoid(control_power, time))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep integration compatible with NumPy 1.x

The package permits NumPy 1.24+ in src/pendulum_simulator/pyproject.toml, but np.trapezoid was introduced in NumPy 2.0. On supported NumPy 1.24–1.26 installations, every call to summarize_transfer raises AttributeError before returning any metrics; use the compatible np.trapz API or raise the minimum NumPy version.

Useful? React with 👍 / 👎.

Comment on lines +138 to +141
mask = (time >= start_s) & (time <= end_s)
if np.count_nonzero(mask) < 2:
raise ValueError("analysis window must contain at least two samples")
return np.flatnonzero(mask)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Integrate the declared window boundaries

When the user-entered start or end is not exactly a trajectory sample—which is normal because the spin boxes accept arbitrary four-decimal values—this mask silently discards both partial boundary intervals. For example, a 0.01–0.29 window on 0.1-spaced data integrates only 0.1–0.2 while reporting the requested bounds, and narrower valid windows raise an uncaught ValueError; interpolate boundary samples or constrain and snap the UI to the sample grid.

AGENTS.md reference: AGENTS.md:L129-L133

Useful? React with 👍 / 👎.

Comment on lines +224 to +228
shaft_com_velocity = wrist_velocity + 0.5 * params.L2 * club_rate[:, None] * club_tangent
tip_velocity = wrist_velocity + params.L2 * club_rate[:, None] * club_tangent
shaft_inertia = params.m2 * params.L2**2 / 12.0
shaft_energy = 0.5 * params.m2 * np.sum(shaft_com_velocity**2, axis=1)
shaft_energy += 0.5 * shaft_inertia * club_rate**2

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Match distal energy to the simulated mass model

Whenever m2 is nonzero, this diagnostic uses a distributed uniform-shaft model, but physics.py simulates the entire effective distal mass m2 + mClub as a point mass at the tip. Consequently, distal_kinetic_energy_j is not the kinetic energy of the trajectory that produced the forces and velocities, so reported distal energy gains can be materially wrong and cannot be reconciled with the model's work balance.

Useful? React with 👍 / 👎.

velocities = result.joint_velocities_at(index)
grip_velocity[index] = velocities["wrist_vel"]
distal_speed[index] = velocities["tip_speed"]
wrist_couple[index] = result.torques_at(index)[1]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Use the clamped wrist torque in work diagnostics

When torque clamping is enabled in the desktop controls, the equations of motion clamp the drive torque, but SimulationResult.torques_at() returns the raw command. This line therefore integrates commanded rather than achieved wrist-couple work—for example, a 100 N·m command with a 20 N·m clamp is reported at five times the applied torque—making the control-work diagnostic inconsistent with the simulated trajectory.

Useful? React with 👍 / 👎.

…6-08-13

Required because main moved under this branch: strict_required_status_checks_policy
is true and allow_update_branch is false, so auto-merge cannot land a
behind-or-conflicting branch and would have sat silently forever.

Only conflict was SPEC.md's Change Log hot-prepend. Kept all three rows, newest
first: CONS-A1's two 2026-08-13 entries (Comment-to-Issue-Converter pick-runner
removal + .codex-worktrees ignore; pdf_renamer SQLite handle leak) above this
branch's 2026-08-12 pendulum drift-transfer entry. Nothing dropped.

.gitignore is taken from main unchanged, so CONS-A1's new .codex-worktrees/ rule
is preserved rather than clobbered.
codex-scheduled added 3 commits August 14, 2026 13:11
…dulum-2026-08-13

# Conflicts:
#	.github/workflows/Jules-Issue-Mention-Handler.yml
#	.github/workflows/PR-Comment-Responder.yml
@dieterolson
dieterolson merged commit 8f654b3 into main Aug 15, 2026
21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Shoulder-Velocity Drift-Transfer Diagnostics and Optimization to the Pendulum Simulator

1 participant