Skip to content

Documentation: issues to settle in the other packages before the final read and the stable release #968

Open

Description

@ocots

Context

The page-by-page review of the documentation is merged (#953, 45 / 45 pages). Many pages point to issues of the other packages, either as a note ("see CTFlows#441"), or as a probe in docs/probes/ that checks the current behaviour and fails once the fix is released. Before a final read of the documentation, and the release of a new stable version, these issues must be settled, and the pages updated.

For each item: when the fix is released, bump the compat if needed, update the page and the probe (the probe fails on purpose, as a reminder), and tick the box.

Other packages: open issues

CTFlows

CTFlows#434 is closed (control-toolbox/CTFlows.jl#442), and control-toolbox/CTFlows.jl#435 too (control-toolbox/CTFlows.jl#444, which replaces the output-grid rule of #442). Once released: (1) dense=false can be dropped from the plots (pages Plot, Flows overview, and the examples; probe plot_flow_saveat.jl); (2) the Plot page (and Flows overview) should say what to do when an integrated trajectory looks polygonal: the default grid is the solver steps, so pass grid=n or grid=AdaptiveGrid(n) (curvature-based, denser where the curves bend) at the call, e.g. f((t0, tf), x0, p0; grid=200). A grid cannot be combined with saveat or with a list of times (IncorrectArgument). Check the wording against the released API. Same check for the closed issues control-toolbox/CTBase.jl#570 (OpenLoop, pages Simulation and Migration), control-toolbox/CTModels.jl#435 (import_ocp_solution, page Save & load), control-toolbox/CTSolvers.jl#234 and control-toolbox/CTBase.jl#565 (GPU errors, probe installation_gpu_errors.jl), control-toolbox/CTSolvers.jl#230 (probe installation_integrators.jl).

CTDirect

CTParser

CTLie

CTBase

OptimalControl

To think about later

  • The Geometry pages: the section has 6 pages for 4 functions. The review suggested 3 pages (overview and lift, brackets with ad, Poisson, @Lie and ∂ₜ, and AD backend). They were kept as they are in docs: page-by-page review of the documentation #953. Decide the structure, once the macros are hygienic (the page on @Lie changes).

Then

  1. Update the pages and the probes for each released fix: julia --project=docs docs/probes/run.jl is the checklist, since a probe for a known bug fails when the bug is fixed.
  2. Final read of the documentation (the review notes and the per-page log are kept by the maintainers).
  3. Release of the new stable version, and switch back the links of "Chat with an AI" to stable/ (they point to dev/ meanwhile).

Activity

  1. ocots commented on Oct 9, 2026

    @ocots
    MemberAuthor
  2. ocots commented on Oct 11, 2026

    @ocots
    MemberAuthor

    How each fix is validated: docs examples, probes, tests

    A fix is only "done" once it is acted in the documentation. Three places can validate it, and each one has a different job.

    1. A documentation example with a hidden @assert (default choice). It runs at every docs build ("run documentation" label), against the released packages, on the path a user follows. It acts the fix for the reader (what used to fail, what works now, with the value checked) and it fails the build if the fix regresses. When an issue is settled, replace the one-line note on the page by a short worked example, with @asserts on the values (rtol of the order of the integrator tolerance, see CTFlows#441/#442). Examples already in place: #481 (the constant dynamics, solved with :adnlp and :exa), the single-flow vs concatenated objectives (CTFlows#441), the Lift error (CTLie#41), the @Lie hygiene trap (CTLie#40).

    2. A probe in docs/probes/ only for what the build cannot execute: a package that must not be loaded, another environment, a fresh session, the absence of output, external URLs. A probe for a known bug checks the current behaviour and fails once the fix is released, as a reminder (not run in CI).

    3. A test in test/suite/ of OptimalControl only when the behaviour belongs to OptimalControl or to the boundary between packages. The behaviour of CTFlows, CTDirect or CTBase is tested in those packages (for instance CTFlows#442/#444 bring about 4000 tests): duplicating it here would tie our CI to their internals and break on their releases.

    Issue Docs example (assert) Probe Test in OptimalControl
    #481 (ADNLPModels 0.8.15) done (Abstract syntax) done yes: no test yet; the bug is at the boundary @def × ADNLPModels × solve, and no single package owns it. Add a small regression test in test/suite/problems/, with 0 * u(t) / constant component, :adnlp and :exa.
    CTLie#40 / OptimalControl#966 import OptimalControl + OptimalControl.@Lie works (replaces the trap section) no yes: in test/suite/reexport/test_ctlie.jl, @Lie evaluated in a module that only has import OptimalControl; and the CTLie name is no longer exported.
    CTParser#356 / OptimalControl#967 import OptimalControl + OptimalControl.@def works no yes: same, in test_ctparser.jl; and the removed re-exports in test_ctmodels.jl / test_examodels.jl.
    CTParser#326, #352–#355 re-read the pages that quote errors of @def; show the new messages in @repl no no (messages are CTParser's; at most one test that the error is a CTException, if we want to pin the contract)
    CTFlows#434/#435/#442/#444/#446, #441 Plot page: grid=n / AdaptiveGrid(n) without dense=false; Constrained arcs: point call with saveat equals the plain flow plot_flow_saveat.jl (turns into a reminder) no (CTFlows tests it)
    CTFlows#439, #440, #437, #438, #436 the page example with the new behaviour or error, asserted (e.g. zf is a pair, not zf[1:2]) installation_gpu_errors.jl for #436 no
    CTDirect#405, #639, #640 Solution object: duals checked against an analytic problem (sign, scale, time stamps) solution_duals.jl no, unless OptimalControl post-processes the duals
    CTDirect#638 Choosing a method: :exa with an explicit time_grid no maybe: a solve routing test (does time_grid reach :exa?) if OptimalControl forwards it
    OptimalControl#964, #965 Initial guess page: init + initial_guess behaviour asserted no yes: these are our own contracts (test/suite/solve/, reexport/)
    CTBase#569 / #573 Plot page: the xlabel / title / ylabel paragraph, asserted (its hidden assert on the old behaviour fails on purpose) no no

    Rule of thumb: example first (it is the proof for the reader), test only if OptimalControl owns the contract or the bug lives between two packages, probe only if the build cannot run it. The tests listed as "yes" can be written now for #481, and together with the fix for #966/#967 and #964/#965.

  3. ocots commented on Oct 13, 2026

    @ocots
    MemberAuthor

    CTFlows #441, #438, #440: what changes in the docs

    Each of these three CTFlows issues now has an open PR (not merged yet). Here is what each page needs once they are released.

    control-toolbox/CTFlows.jl#441: saveat and the point call (PR control-toolbox/CTFlows.jl#457, tests only)

    This is already fixed by CTSolvers 0.6.0 (control-toolbox/CTSolvers.jl#235), which no longer passes saveat to the point call. No CTFlows release is needed for it.

    control-toolbox/CTFlows.jl#438: accessors (PR control-toolbox/CTFlows.jl#458)

    • Accessors (flows/accessors.md), section Gradients:
      • Replace "They only take the full form (t, x, p, v)".
      • The gradients now take the same short forms as the Hamiltonian: ∇H(x, p), (t, x, p) or (x, p, v); for the pseudo-Hamiltonian ones, (x, p, u), …
      • Suggested example: @assert ∇H(x, p) == ∇H(0.0, x, p, Float64[]).
    • Accessors, end of the errors section: replace "On a flow of the state, it is a MethodError for now".
      • Every accessor that does not apply to a flow now raises an IncorrectArgument that says what the flow holds and which accessor to use. For a state flow, the suggestion is vector_field(flow).
      • The error can be shown with the same showerror block as the one for HamiltonianVectorField.
    • Accessors (new): control_law(f) also returns the law of a state flow built from a law, e.g. Flow(ocp, OpenLoop(u)).

    control-toolbox/CTFlows.jl#440: constraint=:label (PR control-toolbox/CTFlows.jl#459)

    The Symbol form now builds g ≥ 0 from the bounds stored in the model:

    • g = c - lb for a lower bound or an equality;
    • g = ub - c for an upper bound.

    A two-sided constraint needs its active side, constraint = :label => :lower or :label => :upper (one side per component for a vector constraint). Without it, the call raises IncorrectArgument.

    • Constrained arcs (flows/constrained-arcs.md):
      • Replace the caveat by an example showing that x(t) - lb ≥ 0, x(t) ≥ lb and lb - x(t) ≤ 0 give the same flow (@assert on p(t₂) = 0).
      • Show the Pair form for a two-sided constraint.
      • The examples may then use the label form.
    • Migration (migration.md, around line 83): the sentence "The Symbol form uses the constraint function stored in the problem, without its bound" is no longer true. Say that it is normalised from its bounds, and mention the Pair form.

    #459 is a breaking change. A label declared with an upper bound (c ≤ ub) changes sign. The release will likely be CTFlows 0.19, so CTFlows = "0.19" must be bumped in Project.toml and in docs/Project.toml.

    Checklist

    • Plot: remove the CompatHelper: bump compat for CTDirect to 0.14, (drop existing compat) #441 sentence (possible now, with CTSolvers 0.6).
    • Accessors: short forms of the gradients, IncorrectArgument on state flows, control_law on controlled flows (after CTFlows#458 is released).
    • Constrained arcs and Migration: Symbol and Pair forms of constraint (after CTFlows#459 is released, compat 0.19).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

documentationImprovements or additions to documentation

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions