From the transforms-module audit (follow-up to #532). Part 2 of 5, after #535.
Problem
act on tangent data secretly reconstructs a jet from the at/at_vel kwarg ladder (prolong_slot in prolong.py), hard-fails for ladder order m > 2 with "use prolong with a full jet instead" — the API admitting its own inadequacy — and the kwarg ladder does not scale (order 3 would need at_acc, ...). Meanwhile Composed's tangent act hand-rolls a shadow 2-jet by advancing at/at_vel with extra per-sub-op act calls, duplicating the clean prolong fold that already exists in composed.py. XLA CSE makes the duplication free at runtime, but it is two implementations of one semantics, and only one of them generalizes.
Proposal
Make prolong(op, tau, jet, chart) THE primitive verb:
act on a point = prolong({0: x})[0]; act on order-m tangent data = assemble jet from anchors -> prolong -> extract slot m. at/at_vel survive as sugar-layer conveniences only.
Composed tangent act delegates to the existing prolong fold (delete the manual anchor threading and its "velocity first" ordering subtlety).
- Consider a single
at_jet: dict[int, CDict] kwarg (with at/at_vel as aliases) so the generic rule can assemble any order.
Coordinate's joint-jet path (register_cx.py) already works this way — consider registering it as prolong(op, tau, x: Coordinate) with act delegating, making the public verb work on bundles directly.
Acceptance
- No m <= 2 ceiling in
act; order-3+ tangent kinds work through the same path (add a Jerk test via the ladder registry)
Composed tangent act == prolong fold by construction (delete the shadow implementation)
- Existing keystone property tests (fast path == generic) and physics acid tests pass unchanged
From the transforms-module audit (follow-up to #532). Part 2 of 5, after #535.
Problem
acton tangent data secretly reconstructs a jet from theat/at_velkwarg ladder (prolong_slotinprolong.py), hard-fails for ladder order m > 2 with "use prolong with a full jet instead" — the API admitting its own inadequacy — and the kwarg ladder does not scale (order 3 would needat_acc, ...). MeanwhileComposed's tangentacthand-rolls a shadow 2-jet by advancingat/at_velwith extra per-sub-opactcalls, duplicating the cleanprolongfold that already exists incomposed.py. XLA CSE makes the duplication free at runtime, but it is two implementations of one semantics, and only one of them generalizes.Proposal
Make
prolong(op, tau, jet, chart)THE primitive verb:acton a point =prolong({0: x})[0];acton order-m tangent data = assemble jet from anchors ->prolong-> extract slot m.at/at_velsurvive as sugar-layer conveniences only.Composedtangentactdelegates to the existingprolongfold (delete the manual anchor threading and its "velocity first" ordering subtlety).at_jet: dict[int, CDict]kwarg (withat/at_velas aliases) so the generic rule can assemble any order.Coordinate's joint-jet path (register_cx.py) already works this way — consider registering it asprolong(op, tau, x: Coordinate)withactdelegating, making the public verb work on bundles directly.Acceptance
act; order-3+ tangent kinds work through the same path (add a Jerk test via the ladder registry)Composedtangent act ==prolongfold by construction (delete the shadow implementation)