Skip to content

📝 docs(spec): Shear matches the code, and Linear gets a section - #762

Merged
nstarman merged 2 commits into
GalacticDynamics:mainfrom
nstarman:claude/spec-transforms-match-code
Aug 19, 2026
Merged

nstarman merged 2 commits into
GalacticDynamics:mainfrom
nstarman:claude/spec-transforms-match-code

Conversation

@nstarman

Copy link
Copy Markdown
Contributor

The third and fourth stale entries in the transforms spec, after the Scale one a
reviewer caught on #750. Found by looking this time, rather than by tripping over them.

Shear documented an API it never had

- - `factor : float` — the shear factor $k$.
- - `chart : AbstractChart` — the chart in which `factor` is expressed (static).
+ - `H : Array[N, N]` — the shear matrix.

dataclasses.fields(Shear(H)) is ("H",). There is no factor and no chart — the
same fiction the Scale section carried. Its inverse and composition were wrong too:

spec said actually
shear.inverse == Shear(-factor, chart) Shear(inv(H))
Shear(k1) + Shear(k2) == Shear(k1 + k2) no composition operator; simplify(a | b) yields a Linear

Linear had no section

It reached the exported-objects table in #730 but was never specified. That is why #750
had to delete a ScaleLinear link rather than ship a dangling anchor. The section
now exists — maths, both fields (M and the static group), inverse, and how simplify
sets the fused group — and that link is restored.

Verification

Every claim was checked against the running code rather than copied from a docstring:

Shear:  fields=['H']   inverse -> Shear   has @: False   H @ inv(H) == I
Linear: fields=['M', 'group']   inverse carries the group across
simplify(Shear | Shear)   -> Linear
simplify(Rotate | Reflect) -> Linear, group=OrthogonalGroup

nox -s docs (the Docs (No Warnings) job) builds clean, so the new anchor resolves —
worth stating explicitly, since a dead anchor is exactly what I avoided in #750.

Spec examples are under CI as of #733: 1369 passed.

Note for later

This is the third section found stale by accident. A test asserting each !!! info
section's Fields against dataclasses.fields would close the class properly. I did
not add one here because it is a different kind of change from a docs correction, and
because the scope needs care — the exported-objects table is deliberately curated (the
charts row omits 50+ names on purpose), so only the per-type sections can be enforced
that way. Happy to follow up if wanted.

Third and fourth stale entries in the transforms spec, after the `Scale` one a
reviewer caught on GalacticDynamics#750. Found by looking this time rather than by accident.

`Shear` was documented with `factor : float` and `chart : AbstractChart`, neither
of which it has -- `dataclasses.fields(Shear(H))` is `("H",)`. Its inverse
(`Shear(-factor, chart)`) and composition (`Shear(k1) + Shear(k2)`) described an
API that never existed: there is no composition operator, and piping two through
`simplify` yields a `Linear`.

`Linear` had no section at all. It reached the exported-objects table in GalacticDynamics#730 but
was never specified, which is why GalacticDynamics#750 had to drop a `Scale` -> `Linear` link
rather than point at a missing anchor. The anchor exists now, so that link is
restored.

Every claim checked against the running code: fields, `inverse`, what `simplify`
returns, and that a fused rotation-and-reflection reports `OrthogonalGroup`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings August 19, 2026 22:06

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Updates the transforms portion of docs/spec.md to reflect the current coordinax.transforms implementation, correcting the documented Shear API/behavior and adding a missing spec section for Linear so that doc anchors and references are valid.

Changes:

  • Fixes the Shear spec to document its actual single field (H) and its simplify/fusion behavior.
  • Adds a new Linear spec section (math definition, fields M/static group, inverse behavior, and fusion semantics).
  • Restores/updates the ScaleLinear cross-reference using the new Linear anchor.

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread docs/spec.md Outdated
@nstarman nstarman added this to the v0.24.0 milestone Aug 19, 2026
@github-actions github-actions Bot added the 📝 Add / update documentation Add or update documentation. label Aug 19, 2026
@codecov

codecov Bot commented Aug 19, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.63%. Comparing base (2cdf14e) to head (17bead1).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #762   +/-   ##
=======================================
  Coverage   96.63%   96.63%           
=======================================
  Files         267      267           
  Lines        9070     9070           
=======================================
  Hits         8765     8765           
  Misses        305      305           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Review follow-up: I wrote that inverting a shear "negates the off-diagonal
entries", generalising from the one elementary shear I checked. It is false as
soon as two off-diagonals chain, because the nilpotent part has a non-zero
square:

    H = [[1, 2, 0], [0, 1, 3], [0, 0, 1]]
    inv(H) = [[1, -2, 6], [0, 1, -3], [0, 0, 1]]
                     ^^ the N^2 term, not -0

`Shear` stores an arbitrary square matrix and inverts it with `jnp.linalg.inv`,
so the spec now says just that.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

@nstarman
nstarman merged commit 85a1909 into GalacticDynamics:main Aug 19, 2026
14 of 15 checks passed
@nstarman
nstarman deleted the claude/spec-transforms-match-code branch August 19, 2026 23:49
nstarman added a commit that referenced this pull request Aug 20, 2026
Three spec sections have now been found describing fields the class does not
have -- `Scale` (#750), `Shear` (#762), and `Tangent` here -- each by accident
rather than by looking. This closes the class: every `!!! info` section with a
**Fields** block is checked against `dataclasses.fields`.

`Tangent` was the fifth stale entry. It listed a `manifold` field that has never
existed; the manifold is reached through `M`, a property derived from the chart.
Its "Post-init checks" were wrong too -- the hook is `__check_init__`, and it
calls `M.check_chart(chart)`, not `manifold.has_chart(chart)`.

Two deliberate limits:

Sets, not sequences. `Translate` defines its own `__init__` whose parameter
order is the useful one to document and differs from `dataclasses.fields`;
enforcing order would fail a section that is right.

Per-type sections only. The exported-objects table is a curated summary -- the
`coordinax.charts` row omits 50-odd class names on purpose -- so it is not an
`__all__` mirror and is left alone.

Both spellings of a Fields block are parsed, bullet list and table, and a guard
test asserts the parser still finds sections: a regex that quietly matches
nothing would pass forever.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

📝 Add / update documentation Add or update documentation.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants